- Rename `config/autoload/local.php.dist` to `local.php`
- Edit the `local.php` and insert your database credentials
- Rename `public/.htaccess_original` to `.htaccess`
(if you experience webserver problems, try instead renaming `public/.htacess_alternative` to `.htaccess`)
2. Enable UNIX write permission for
- `data/cache/`
- `data/log/`
- `data/session/`
- `public/docs-client/upload/`
- `public/imgs-client/upload/`
3. Setup the database by calling the `setup.php`
4. Delete the setup tool
- `public/setup.php`
5. Delete any files in the following directory:
- `data/cache/`
6. Optionally customize public files:
- `css-client/default.css` for custom CSS
- `imgs-client/icons/fav.ico`
- `imgs-client/layout/logo.png` (75x75)
## Issues
If you run into any issues: Many problems have already been discussed and solved in the
[GitHub issue section](https://github.com/tkrebs/ep3-bs/issues).
## Deployment
Once you are satisfied with the system and want to use it in the wild, 🚨
please make sure to set the **Apache document root directly to the `public` directory**
so that your domain will read like this:
`https://example.com/`
And not like this:
`https://example.com/public/`
The latter is a huge security threat, that is only acceptable while testing the system.
You may also consider to use a subdomain, like this:
`https://bookings.example.com/`
## Custom modules
Simply copy custom or third-party modules into the `modulex` directory and they will be loaded automatically.
================================================
FILE: LICENSE
================================================
Copyright (c) 2025 Tobias Krebs
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.
================================================
FILE: README.md
================================================
# ep-3 Bookingsystem
The ep-3 Bookingsystem is an open source (MIT licensed) web application to enable users to check and book free places of
an arbitrary facility easily online via one huge calendar.
It was initially developed to enable booking free squares of a covered court for a tennis club, improved along some
versions, tried to offer commercially as a SaaS - and finally released as open source software.
Among its primary features are extensive customization capabilities (thus making it interesting even outside the tennis
branch), multilingualism (currently shipped with english and german), an interactive, easy-to-use calendar, an
easy-to-use and easy-to-understand backend, a consistent and clear visual design and a fully responsive layout (thus
looking nice on mobile devices as well).
More features may be explored via our website (http://bs.hbsys.de/) or simply by downloading and trying the system
yourself.
## Documentation
- Installation instructions can be found in [INSTALL.md](https://github.com/tkrebs/ep3-bs/blob/master/INSTALL.md)
- Update instructions can be found in [UPDATE.md](https://github.com/tkrebs/ep3-bs/blob/master/UPDATE.md)
Further documentation and technical details can be found in the following directory:
```
data/docs/
```
## Architecture
The system is based on the well-known LAMP stack (Linux, Apache 2, MySQL 5+, PHP 8.1+) and the powerful
[Zend Framework 2](http://framework.zend.com/) (2.5).
As of version 1.9.0, it requires at least PHP 8.1 and is compatible and tested with up to PHP 8.4.
Dependencies are managed with [Composer](https://getcomposer.org/).
The source code is version controlled with [Git](http://git-scm.com/) and hosted at [GitHub](https://github.com/).
The link to the GitHub repository is
```
https://github.com/tkrebs/ep3-bs
```
where you can find stable and (latest) development releases.
## Versions
The current version is 1.9.0 from May 2025.
Version 1.9.0 applied IDE inspections for PHP 8.4 compatibility.
Version 1.8.1 fixes an email sending related bug.
Version 1.8.0 provides compatibility with PHP 8.1 by overriding and fixing the essential Zend Framework 2 components.
It also fixes some bugs, added a file-storage-only mail option and removes some legacy code (mainly, the file manager).
Version 1.7.0 provides compatibility with PHP 7.4 by overriding and fixing some of the Zend Framework 2 components.
Version 1.6.4 introduced some features required during the COVID-19 pandemic, including limits to active concurrent bookings and minimum booking ranges. It also includes minor bug fixes and improvements.
Version 1.6.3 introduced some GDPR compliance based changes and requested features.
Version 1.6.2 changed the configuration behaviour and requires some manual changes (see data/docs/update.txt). Otherwise, the update will not work.
Version 1.6 introduced some requested features and fixed quite some bugs. It also introduced better support for custom translations and modules.
Version 1.5 introduced some requested features (billing administration, custom billing statuses and colors) and fixed some bugs.
Version 1.4 introduced some requested features and the latest third party libraries and frameworks.
## Bug reports, feature requests, ideas ...
We use the GitHub Issue Tracker for such things:
https://github.com/tkrebs/ep3-bs/issues
================================================
FILE: UPDATE.md
================================================
# Update of the ep-3 Bookingsystem from an existing/older version
## 1. Backup
First and most importantly: Backup your database and entire project directory!
## 2. Clear cache
After every update you should delete all files within the
- `data/cache/`
directory.
If you haven't made any changes to the core files, your configuration, customizations and data should stay intact
after the update.
## Update from 1.8.1 to `1.9.0`
- Replace the `module/` directory
- Replace the `src/` directory
## Update from 1.8.0 to `1.8.1`
- Replace the `vendor/` directory
## Update from 1.7.0 to `1.8.0`
🚨 Warnings:
- This version is only compatible with **PHP 8.1** or higher
- Due to extensive code changes for this compatibility, there may appear new (and not yet "issued") bugs.
Please test this version thoroughly before deploying in production.
Also, please report any PHP 8.1 related bugs in our [GitHub issue section](https://github.com/tkrebs/ep3-bs/issues).
- The bundled *file manager* has been removed in this version, as it was outdated and considered insecure.
Until we have implemented a new solution, you may have to upload files the old-fashioned way ((S)FTP or similar).
Update steps:
- Replace the `data/docs/` directory
- Create a `data/mails` directory
- Replace the `module/` directory
- If you made custom changes to the code, you have to migrate them manually
- Replace files:
- `public/index.php`
- `public/setup.php`
- Delete the directory `public/vendor/filemanager`:
This is technically not necessary, but recommended.
- Paste the new `src/` directory
- Replace the `vendor/` directory
- Technically not necessary, but for consistency reasons:
Replace the files in the project directory:
- `composer.json`
- `composer.lock`
- `CONTRIBUTE.md`
- `INSTALL.md`
- `LICENSE`
- `README.md`
- `UPDATE.md`
- `VERSION`
- Delete files:
- `INSTALL` (without file extension)
- `README` (without file extension)
## Update from 1.6.4 to `1.7.0`
Replace the following directories:
- `module/`
- `vendor/`
## Update from 1.6.3 to `1.6.4`
There are no steps necessary when updating from version `1.6.3`.
## Update from 1.6.2 to `1.6.3`
Replace the following directories:
- `data/docs/`
- `data/res/i18n/`
- `module/`
- `public/js/jquery/`
- `vendor/`
(alternatively, you may update dependencies via Composer after replacing the `composer.json`)
- All single files in the project root directory
## Update from 1.6 to `1.6.2`
There have been some internal changes to the configuration directory. Replace the following files:
- `config/init.php.dist`
- `config/init.php`
(and edit it according to your needs; if it does not yet exist, create it by copying `init.php.dist`)
- `data/docs/*`
- `public/index.php`
- `vendor/*`
(alternatively, you may update dependencies via Composer after replacing the `composer.json`)
- All single files in the project root directory
## Update from 1.4 or 1.5 to `1.6`
Replace the following directories and files with the new ones:
- `config/application.php`
- `config/modules.php`
- `config/setup.php`
- `data/res/`
(if you have custom translations you ~~can~~ should now place them in `data/res/i18n-custom/`)
- `module/`
- `modulex/`
- `public/js/`
- `public/index.php`
## Update from older versions to `1.4` or `1.5`
Replace the following directories and files with the new ones:
- `data/res/`
- `module/`
- `public/css/`
- `public/docs/`
- `public/imgs/`
- `public/js/`
- `public/misc/`
- `public/vendor/`
- `index.php`
- `vendor/`
(alternatively, you may update dependencies via Composer after replacing the `composer.json`)
- All single files in the project root directory
================================================
FILE: VERSION
================================================
1.9.0
================================================
FILE: composer.json
================================================
{
"name": "tkrebs/ep3-bs",
"description": "Online booking system for courts",
"license": "MIT",
"homepage": "https://bs.hbsys.de/",
"require": {
"php": ">=8.1",
"ext-intl": "*",
"ext-pdo": "*",
"zendframework/zend-authentication": "^2.7.0",
"zendframework/zend-cache": "^2.9.0",
"zendframework/zend-console": "^2.8.0",
"zendframework/zend-debug": "^2.6.0",
"zendframework/zend-di": "^2.6.1",
"zendframework/zend-diactoros": "^2.2.1",
"zendframework/zend-file": "^2.8.3",
"zendframework/zend-i18n-resources": "^2.6.1",
"zendframework/zend-log": "^2.12.0",
"zendframework/zend-version": "^2.5.1",
"true/punycode": "^2.1"
},
"autoload": {
"psr-4": {
"Zend\\Config\\": "src/Zend/Config/src/",
"Zend\\Crypt\\": "src/Zend/Crypt/src/",
"Zend\\Db\\": "src/Zend/Db/src/",
"Zend\\Escaper\\": "src/Zend/Escaper/src/",
"Zend\\EventManager\\": "src/Zend/EventManager/src/",
"Zend\\Filter\\": "src/Zend/Filter/src/",
"Zend\\Form\\": "src/Zend/Form/src/",
"Zend\\Http\\": "src/Zend/Http/src/",
"Zend\\Hydrator\\": "src/Zend/Hydrator/src/",
"Zend\\I18n\\": "src/Zend/I18n/src/",
"Zend\\InputFilter\\": "src/Zend/InputFilter/src/",
"Zend\\Json\\": "src/Zend/Json/src/",
"Zend\\Loader\\": "src/Zend/Loader/src/",
"Zend\\Mail\\": "src/Zend/Mail/src/",
"Zend\\Math\\": "src/Zend/Math/src/",
"Zend\\Mime\\": "src/Zend/Mime/src/",
"Zend\\ModuleManager\\": "src/Zend/ModuleManager/src/",
"Zend\\Mvc\\": "src/Zend/Mvc/src/",
"Zend\\Serializer\\": "src/Zend/Serializer/src/",
"Zend\\ServiceManager\\": "src/Zend/ServiceManager/src/",
"Zend\\Session\\": "src/Zend/Session/src/",
"Zend\\Stdlib\\": "src/Zend/Stdlib/src/",
"Zend\\Uri\\": "src/Zend/Uri/src/",
"Zend\\Validator\\": "src/Zend/Validator/src/",
"Zend\\View\\": "src/Zend/View/src/"
}
}
}
================================================
FILE: config/.gitignore
================================================
init.php
================================================
FILE: config/application.php
================================================
array_merge([
/**
* Application core modules
*
* Usually, you don't have to change these
* (but you can, of course ;)
*/
'Backend',
'Base',
'Booking',
'Calendar',
'Event',
'Frontend',
'Service',
'Square',
'User',
/**
* Custom modules
*
* Place your own, custom or third party modules in the modulex/ directory
* and they will be loaded automatically.
*/
], include 'modulexes.php'),
/**
* Some further internal settings,
* don't worry about these.
*/
'module_listener_options' => [
'config_glob_paths' => [
'config/autoload/{,*.}{global,local}.php',
],
'module_paths' => [
'module',
'modulex',
'vendor',
],
'config_cache_enabled' => ! EP3_BS_DEV,
'config_cache_key' => 'ep3-bs',
'module_map_cache_enabled' => ! EP3_BS_DEV,
'module_map_cache_key' => 'ep3-bs',
'cache_dir' => getcwd() . '/data/cache/',
],
];
================================================
FILE: config/autoload/.gitignore
================================================
local.php
================================================
FILE: config/autoload/global.php
================================================
[
'driver' => 'pdo_mysql',
'charset' => 'UTF8',
],
'cookie_config' => [
'cookie_name_prefix' => 'ep3-bs',
],
'redirect_config' => [
'cookie_name' => 'ep3-bs-origin',
'default_origin' => 'frontend',
],
'session_config' => [
'name' => 'ep3-bs-session',
'save_path' => getcwd() . '/data/session/',
'use_cookies' => true,
'use_only_cookies' => true,
],
];
================================================
FILE: config/autoload/local.php.dist
================================================
[
'database' => '?',
'username' => '?',
'password' => '?',
'hostname' => 'localhost',
'port' => null,
],
'mail' => [
'type' => 'sendmail', // or 'smtp' or 'smtp-tls' (or 'file', to not send, but save to file (data/mails/))
'address' => 'info@bookings.example.com',
// Make sure 'bookings.example.com' matches the hosting domain when using type 'sendmail'
'host' => '?', // for 'smtp' type only, otherwise remove or leave as is
'user' => '?', // for 'smtp' type only, otherwise remove or leave as is
'pw' => '?', // for 'smtp' type only, otherwise remove or leave as is
'port' => 'auto', // for 'smtp' type only, otherwise remove or leave as is
'auth' => 'plain', // for 'smtp' type only, change this to 'login' if you have problems with SMTP authentication
],
'i18n' => [
'choice' => [
'en-US' => 'English',
'de-DE' => 'Deutsch',
// More possible languages:
// 'fr-FR' => 'Français',
// 'hu-HU' => 'Magyar',
],
'currency' => 'EUR',
// The language is usually detected from the user's web browser.
// If it cannot be detected automatically and there is no cookie from a manual language selection,
// the following locale will be used as the default "fallback":
'locale' => 'de-DE',
],
];
================================================
FILE: config/init.php.dist
================================================
[
'Base',
'Setup',
'Square',
'User',
],
'module_listener_options' => [
'config_glob_paths' => [
'config/autoload/{,*.}{global,local}.php',
],
'module_paths' => [
'module',
'vendor',
],
'config_cache_enabled' => ! EP3_BS_DEV,
'config_cache_key' => 'ep3-bs-setup',
'module_map_cache_enabled' => ! EP3_BS_DEV,
'module_map_cache_key' => 'ep3-bs-setup',
'cache_dir' => getcwd() . '/data/cache/',
],
];
================================================
FILE: data/backup/.gitignore
================================================
*
!.gitignore
================================================
FILE: data/cache/.gitignore
================================================
*
!.gitignore
================================================
FILE: data/db/ep3-bs.sql
================================================
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
--
-- Datenbank: `ep3-bs`
--
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `bs_bookings`
--
CREATE TABLE IF NOT EXISTS `bs_bookings` (
`bid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`uid` int(10) unsigned NOT NULL,
`sid` int(10) unsigned NOT NULL,
`status` varchar(64) NOT NULL COMMENT 'single|subscription|cancelled',
`status_billing` varchar(64) NOT NULL COMMENT 'pending|paid|cancelled|uncollectable',
`visibility` varchar(64) NOT NULL COMMENT 'public|private',
`quantity` int(10) unsigned NOT NULL,
`created` datetime NOT NULL,
PRIMARY KEY (`bid`),
KEY `sid` (`sid`),
KEY `uid` (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `bs_bookings_bills`
--
CREATE TABLE IF NOT EXISTS `bs_bookings_bills` (
`bbid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`bid` int(10) unsigned NOT NULL,
`description` varchar(512) NOT NULL,
`quantity` int(10) unsigned DEFAULT NULL,
`time` int(10) unsigned DEFAULT NULL,
`price` int(10) NOT NULL,
`rate` int(10) unsigned NOT NULL,
`gross` tinyint(1) NOT NULL,
PRIMARY KEY (`bbid`),
KEY `bid` (`bid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `bs_bookings_meta`
--
CREATE TABLE IF NOT EXISTS `bs_bookings_meta` (
`bmid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`bid` int(10) unsigned NOT NULL,
`key` varchar(64) NOT NULL,
`value` text NOT NULL,
PRIMARY KEY (`bmid`),
KEY `bid` (`bid`),
KEY `key` (`key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `bs_events`
--
CREATE TABLE IF NOT EXISTS `bs_events` (
`eid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`sid` int(10) unsigned DEFAULT NULL COMMENT 'NULL for all',
`status` varchar(64) NOT NULL DEFAULT 'enabled' COMMENT 'enabled',
`datetime_start` datetime NOT NULL,
`datetime_end` datetime NOT NULL,
`capacity` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`eid`),
KEY `sid` (`sid`),
KEY `datetime_start` (`datetime_start`),
KEY `datetime_end` (`datetime_end`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `bs_events_meta`
--
CREATE TABLE IF NOT EXISTS `bs_events_meta` (
`emid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`eid` int(10) unsigned NOT NULL,
`key` varchar(64) NOT NULL,
`value` text NOT NULL,
`locale` varchar(8) DEFAULT NULL,
PRIMARY KEY (`emid`),
KEY `eid` (`eid`),
KEY `key` (`key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `bs_options`
--
CREATE TABLE IF NOT EXISTS `bs_options` (
`oid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`key` varchar(64) NOT NULL,
`value` text NOT NULL,
`locale` varchar(8) DEFAULT NULL,
PRIMARY KEY (`oid`),
KEY `key` (`key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `bs_reservations`
--
CREATE TABLE IF NOT EXISTS `bs_reservations` (
`rid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`bid` int(10) unsigned NOT NULL,
`date` date NOT NULL,
`time_start` time NOT NULL,
`time_end` time NOT NULL,
PRIMARY KEY (`rid`),
KEY `bid` (`bid`),
KEY `date` (`date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `bs_reservations_meta`
--
CREATE TABLE IF NOT EXISTS `bs_reservations_meta` (
`rmid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`rid` int(10) unsigned NOT NULL,
`key` varchar(64) NOT NULL,
`value` text NOT NULL,
PRIMARY KEY (`rmid`),
KEY `rid` (`rid`),
KEY `key` (`key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `bs_squares`
--
CREATE TABLE IF NOT EXISTS `bs_squares` (
`sid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(64) NOT NULL,
`status` varchar(64) NOT NULL DEFAULT 'enabled' COMMENT 'disabled|readonly|enabled',
`priority` float NOT NULL DEFAULT '1',
`capacity` int(10) unsigned NOT NULL,
`capacity_heterogenic` tinyint(1) NOT NULL,
`allow_notes` tinyint(1) NOT NULL DEFAULT 0,
`time_start` time NOT NULL,
`time_end` time NOT NULL,
`time_block` int(10) unsigned NOT NULL,
`time_block_bookable` int(10) unsigned NOT NULL,
`time_block_bookable_max` int(10) unsigned DEFAULT NULL,
`min_range_book` int(10) unsigned DEFAULT 0,
`range_book` int(10) unsigned DEFAULT NULL,
`max_active_bookings` int(10) unsigned DEFAULT 0,
`range_cancel` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`sid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `bs_squares_coupons`
--
CREATE TABLE IF NOT EXISTS `bs_squares_coupons` (
`scid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`sid` int(10) unsigned DEFAULT NULL COMMENT 'NULL for all',
`code` varchar(64) NOT NULL,
`date_start` datetime DEFAULT NULL,
`date_end` datetime DEFAULT NULL,
`discount_for_booking` int(10) unsigned NOT NULL,
`discount_for_products` int(10) unsigned NOT NULL,
`discount_in_percent` tinyint(1) NOT NULL,
PRIMARY KEY (`scid`),
KEY `sid` (`sid`),
KEY `code` (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `bs_squares_meta`
--
CREATE TABLE IF NOT EXISTS `bs_squares_meta` (
`smid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`sid` int(10) unsigned NOT NULL,
`key` varchar(64) NOT NULL,
`value` text NOT NULL,
`locale` varchar(8) DEFAULT NULL,
PRIMARY KEY (`smid`),
KEY `sid` (`sid`),
KEY `key` (`key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `bs_squares_pricing`
--
CREATE TABLE IF NOT EXISTS `bs_squares_pricing` (
`spid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`sid` int(10) unsigned DEFAULT NULL COMMENT 'NULL for all',
`priority` int(10) unsigned NOT NULL,
`date_start` date NOT NULL,
`date_end` date NOT NULL,
`day_start` tinyint(3) unsigned DEFAULT NULL COMMENT 'Day of the week',
`day_end` tinyint(3) unsigned DEFAULT NULL,
`time_start` time DEFAULT NULL,
`time_end` time DEFAULT NULL,
`price` int(10) unsigned DEFAULT NULL,
`rate` int(10) unsigned DEFAULT NULL,
`gross` tinyint(1) DEFAULT NULL,
`per_time_block` int(10) unsigned DEFAULT NULL,
`per_quantity` tinyint(1) DEFAULT NULL,
PRIMARY KEY (`spid`),
KEY `sid` (`sid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `bs_squares_products`
--
CREATE TABLE IF NOT EXISTS `bs_squares_products` (
`spid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`sid` int(10) unsigned DEFAULT NULL COMMENT 'NULL for all',
`priority` int(10) unsigned NOT NULL,
`date_start` date DEFAULT NULL,
`date_end` date DEFAULT NULL,
`name` varchar(128) NOT NULL,
`description` text,
`options` varchar(512) NOT NULL,
`price` int(10) unsigned NOT NULL,
`rate` int(10) unsigned NOT NULL,
`gross` tinyint(1) NOT NULL,
`locale` varchar(8) DEFAULT NULL,
PRIMARY KEY (`spid`),
KEY `sid` (`sid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `bs_users`
--
CREATE TABLE IF NOT EXISTS `bs_users` (
`uid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`alias` varchar(128) NOT NULL,
`status` varchar(64) NOT NULL DEFAULT 'placeholder' COMMENT 'placeholder|deleted|blocked|disabled|enabled|assist|admin',
`email` varchar(128) DEFAULT NULL,
`pw` varchar(256) DEFAULT NULL,
`login_attempts` tinyint(3) unsigned DEFAULT NULL,
`login_detent` datetime DEFAULT NULL,
`last_activity` datetime DEFAULT NULL,
`last_ip` varchar(64) DEFAULT NULL,
`created` datetime DEFAULT NULL,
PRIMARY KEY (`uid`),
KEY `alias` (`alias`),
KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `bs_users_meta`
--
CREATE TABLE IF NOT EXISTS `bs_users_meta` (
`umid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`uid` int(10) unsigned NOT NULL,
`key` varchar(64) NOT NULL,
`value` text NOT NULL,
PRIMARY KEY (`umid`),
KEY `key` (`key`),
KEY `uid` (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Constraints der exportierten Tabellen
--
--
-- Constraints der Tabelle `bs_bookings`
--
ALTER TABLE `bs_bookings`
ADD CONSTRAINT `bs_bookings_ibfk_3` FOREIGN KEY (`sid`) REFERENCES `bs_squares` (`sid`),
ADD CONSTRAINT `bs_bookings_ibfk_4` FOREIGN KEY (`uid`) REFERENCES `bs_users` (`uid`);
--
-- Constraints der Tabelle `bs_bookings_bills`
--
ALTER TABLE `bs_bookings_bills`
ADD CONSTRAINT `bs_bookings_bills_ibfk_1` FOREIGN KEY (`bid`) REFERENCES `bs_bookings` (`bid`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints der Tabelle `bs_bookings_meta`
--
ALTER TABLE `bs_bookings_meta`
ADD CONSTRAINT `bs_bookings_meta_ibfk_1` FOREIGN KEY (`bid`) REFERENCES `bs_bookings` (`bid`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints der Tabelle `bs_events`
--
ALTER TABLE `bs_events`
ADD CONSTRAINT `bs_events_ibfk_1` FOREIGN KEY (`sid`) REFERENCES `bs_squares` (`sid`);
--
-- Constraints der Tabelle `bs_events_meta`
--
ALTER TABLE `bs_events_meta`
ADD CONSTRAINT `bs_events_meta_ibfk_1` FOREIGN KEY (`eid`) REFERENCES `bs_events` (`eid`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints der Tabelle `bs_reservations`
--
ALTER TABLE `bs_reservations`
ADD CONSTRAINT `bs_reservations_ibfk_1` FOREIGN KEY (`bid`) REFERENCES `bs_bookings` (`bid`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints der Tabelle `bs_reservations_meta`
--
ALTER TABLE `bs_reservations_meta`
ADD CONSTRAINT `bs_reservations_meta_ibfk_1` FOREIGN KEY (`rid`) REFERENCES `bs_reservations` (`rid`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints der Tabelle `bs_squares_coupons`
--
ALTER TABLE `bs_squares_coupons`
ADD CONSTRAINT `bs_squares_coupons_ibfk_1` FOREIGN KEY (`sid`) REFERENCES `bs_squares` (`sid`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints der Tabelle `bs_squares_meta`
--
ALTER TABLE `bs_squares_meta`
ADD CONSTRAINT `bs_squares_meta_ibfk_1` FOREIGN KEY (`sid`) REFERENCES `bs_squares` (`sid`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints der Tabelle `bs_squares_pricing`
--
ALTER TABLE `bs_squares_pricing`
ADD CONSTRAINT `bs_squares_pricing_ibfk_1` FOREIGN KEY (`sid`) REFERENCES `bs_squares` (`sid`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints der Tabelle `bs_squares_products`
--
ALTER TABLE `bs_squares_products`
ADD CONSTRAINT `bs_squares_products_ibfk_1` FOREIGN KEY (`sid`) REFERENCES `bs_squares` (`sid`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints der Tabelle `bs_users_meta`
--
ALTER TABLE `bs_users_meta`
ADD CONSTRAINT `bs_users_meta_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `bs_users` (`uid`) ON DELETE CASCADE ON UPDATE CASCADE;
================================================
FILE: data/docs/install.txt
================================================
The installation instructions have been moved to
INSTALL.md
in the project directory.
Or:
https://github.com/tkrebs/ep3-bs/blob/master/INSTALL.md
================================================
FILE: data/docs/internals/architecture.txt
================================================
- index.php changes working directory, loads and registers the standard autoloader and invokes the application init()
method with the application's global config (which essentially determines which modules to load,
where to find them and which other global config files should be loaded and merged with each module config)
- init() creates and prepares ServiceManager (optionally configured with passed array)
- init() creates and prepares ModuleManager (via ServiceManager)
* prepares separate service locators for controllers, controller plugins, form elements, view helpers, etc.
- ModuleManager triggers
1. loadModules
1. loadModule.resolve
* load module via ModuleAutoloader
* instantiate module class
2. loadModule (each with own ModuleEvent)
* invokes module's init method (if available)
* registers module's onBootstrap method (if available)
* merges all arrays from module's config file and get*() methods
2. loadModules.post (free for custom listeners)
- Now we have a complete config array merged together from all loaded modules and autoload config files.
Also we have separate service locators for the controllers, controller plugins, view helpers, etc.
Config and ServiceManager are now passed to a newly created application object.
- bootstrap() registers route, dispatch and view listeners
- bootstrap() triggers
1. bootstrap
* view manager prepares itself
* custom module's onBootstraps are called
- run() triggers
1. route
* match request against configured route (since usually a route stack/tree, match against all route rules)
* if found, return RouteMatch, otherwise trigger dispatch.error
2. dispatch
* determine controller from RouteMatch
* if found and dispatchable, call it, otherwise trigger dispatch.error
3. render
4. finish
================================================
FILE: data/docs/internals/backend/booking.ep
================================================
Untitled Page1400976092359_19571350900true#FFFFFFFFtransparentBooking-Administration
Edit datetime range
- Time interval - Square ]]>
- Date interval - Time interval - Square
(choose defaults if params are missing) ]]>
(choose defaults if params are missing)
Free
Occupied
(by reservations, whose bookings are not cancelled) ]]>
(by reservations, whose bookings are not cancelled)
]]>
One reservation
]]>
Multiple reservations
Single
]]>
Choose one reservation
by rid param ]]>
by rid param
]]>
Edit booking/reservation together
Subscription
]]>
Choose edit mode
(user, square, ...) ]]>
Edit booking part (user, square, ...)
(date and time) ]]>
Edit reservation part (date and time)
(irrelevant inputs are greyed out) ]]>
(irrelevant inputs are greyed out)
(irrelevant inputs are greyed out) ]]>
(irrelevant inputs are greyed out)
================================================
FILE: data/docs/internals/on-update.txt
================================================
- Update features
- Update documentation
- Update project files
- README.md
- VERSION
- Update package
~ Update demo
================================================
FILE: data/docs/options.txt
================================================
Options:
- client.name.full
- client.name.short
- client.contact.email
- client.contact.email.user-notifications (optional) true|false
- client.contact.phone
- client.website URL
- client.website.contact URL
- client.website.imprint URL
- client.website.privacy URL
- service.name.full
- service.name.short
- service.user.registration true|false
- service.user.registration.message (optional)
- service.user.registration.terms.file (optional)
- service.user.registration.terms.name (optional)
- service.user.registration.privacy.file (optional)
- service.user.registration.privacy.name (optional)
- service.user.activation immediate|manual|manual-email|email
- service.calendar.days int
- service.calendar.day-exceptions (optional)
- service.website URL
- service.meta.description (optional)
- service.maintenance (optional) true|false
- service.maintenance.message (optional)
- service.branding (optional) true|false
- service.branding.name (optional)
- service.branding.website (optional)
- service.pricing.visibility public|private|never
- service.pricing.payment none|invoice|paypal|invoice,paypal
- service.status-values.billing (optional)
- subject.help HTML
- subject.about HTML
- subject.type (including determiner)
- subject.square.type
- subject.square.type.plural
- subject.square.unit
- subject.square.unit.plural
Booking meta keys:
- date_start (for subscriptions)
- date_end (for subscriptions)
- time_start (for subscriptions)
- time_end (for subscriptions)
- repeat (for subscriptions)
- notes (optional)
- creator (optional, if created by admin or assist)
- cancellor (optional, if cancelled by admin or assist)
- cancelled (optional, if cancelled by admin or assist)
- player-names (optional, if multi-player bookinh)
Reservation meta keys:
- notes (optional)
Event meta keys:
- name
- description HTML
- notes (optional)
Square meta keys:
- info.pre (optional)
- info.post (optional)
- info.capacity (optional) true|false
- rules.text (optional)
- rules.document.file (optional)
- rules.document.name (optional)
- readonly.message (optional)
- public_names (optional) true|false
- private_names (optional) true|false
- capacity-ask-names (optional)
- label.free (optional)
- pseudo-time-block-bookable (optional) true|false
User meta keys:
- gender
- firstname
- lastname
- street
- zip
- city
- phone
- birthdate (optional)
- locale (optional)
- allow.{privilege} (optional) true|false
- notification.bookings (optional) true|false
- deletion.reason (optional)
- legacy-pw (optional)
- notes (optional)
================================================
FILE: data/docs/privileges.txt
================================================
- Admin users can always do everything
- Assist users can do according to their meta values set to "true":
- allow.admin.user
- allow.admin.booking
- allow.admin.event
- allow.admin.config
- allow.admin.see-menu
- allow.calendar.see-past
- allow.calendar.see-data
- allow.calendar.create-single-bookings (requires calendar.see-data)
- allow.calendar.cancel-single-bookings (requires calendar.see-data)
- allow.calendar.delete-single-bookings (requires calendar.see-data)
- allow.calendar.create-subscription-bookings (requires calendar.see-data)
- allow.calendar.cancel-subscription-bookings (requires calendar.see-data)
- allow.calendar.delete-subscription-bookings (requires calendar.see-data)
================================================
FILE: data/docs/update.txt
================================================
The update instructions have been moved to
UPDATE.md
in the project directory.
Or:
https://github.com/tkrebs/ep3-bs/blob/master/UPDATE.md
================================================
FILE: data/log/.gitignore
================================================
*
!.gitignore
================================================
FILE: data/mails/.gitignore
================================================
*
!.gitignore
================================================
FILE: data/res/blacklist-emails.txt
================================================
.mailexpire.com
.spamtrail.com
@0815.ru
@10minutemail.com
@3d-painting.com
@antichef.net
@BeefMilk.com
@bio-muesli.info
@bio-muesli.net
@cust.in
@despammed.com
@DingBone.com
@discardmail.com
@discardmail.de
@dontsendmespam.de
@edv.to
@emailias.com
@ero-tube.org
@film-blog.biz
@FudgeRub.com
@geschent.biz
@great-host.in
@guerillamail.org
@imails.info
@jetable.com
@kulturbetrieb.info
@kurzepost.de
@LookUgly.com
@mail4trash.com
@mailinator.com
@mailnull.com
@nervmich.net
@nervtmich.net
@nomail2me.com
@nurfuerspam.de
@objectmail.com
@owlpic.com
@proxymail.eu
@rcpt.at
@recode.me
@s0ny.net
@sandelf.de
@SmellFear.com
@sneakemail.com
@snkmail.com
@sofort-mail.de
@spam.la
@spambog.com
@spambog.de
@spambog.ru
@spamex.com
@spamgourmet.com
@spammotel.com
@squizzy.de
@super-auswahl.de
@teewars.org
@tempemail.net
@trash-mail.at
@trash-mail.com
@trash2009.com
@trashmail.at
@trashmail.de
@trashmail.me
@trashmail.net
@trashmail.ws
@watch-harry-potter.com
@watchfull.net
@wegwerf-email.net
@wegwerfadresse.de
@wegwerfmail.de
@wegwerfmail.net
@wegwerfmail.org
@willhackforfood.biz
@yopmail.com
================================================
FILE: data/res/i18n/de-DE/backend.php
================================================
'Benutzer',
'Create, edit or delete the users of your system' => 'Erstellen, bearbeiten oder löschen Sie Benutzer Ihres Systems',
'Bookings' => 'Buchungen',
'Create, edit or delete the bookings of your system' => 'Erstellen, bearbeiten oder löschen Sie Buchungen Ihres Systems',
'Event' => 'Veranstaltung',
'Events' => 'Veranstaltungen',
'Create, edit or delete the events of your system' => 'Erstellen, bearbeiten oder löschen Sie Veranstaltungen Ihres Systems',
'Statistic' => 'Statistik',
'User-Statistic' => 'Benutzer-Statistik',
'Booking-Statistic' => 'Buchungs-Statistik',
'Event-Statistic' => 'Veranstaltungs-Statistik',
'Configuration' => 'Einstellungen',
'Configuration has been saved' => 'Einstellungen wurden gespeichert',
'Configuration has been updated' => 'Einstellungen wurden aktualisiert',
'Configuration is (partially) invalid' => 'Einstellung sind (teilweise) ungültig',
'Configure your system just as you need it' => 'Passen Sie Ihr System nach Ihren Wünschen an',
'Here you can configure and fine tune your system just as you need it.'
=> 'Hier können Sie Ihr System Ihren Wünschen entsprechend anpassen und einstellen.',
'User-Administration' => 'Benutzer-Verwaltung',
'Here you can create, edit or delete the users of your system.' => 'Hier können Sie die Benutzer Ihres Systems erstellen, bearbeiten oder löschen.',
'Booking-Administration' => 'Buchungs-Verwaltung',
'Here you can create, edit or delete the bookings of your system.' => 'Hier können Sie die Buchungen Ihres Systems erstellen, bearbeiten oder löschen.',
'Event-Administration' => 'Veranstaltungs-Verwaltung',
'Here you can create, edit or delete the events of your system.' => 'Hier können Sie die Veranstaltungen Ihres Systems erstellen, bearbeiten oder löschen.',
'Name or number' => 'Name oder Nummer',
'Search' => 'Suche',
'Advanced search' => 'Erweiterte Suche',
'%sNo users found%s for this search' => '%sKeine Benutzer%s für diese Suche gefunden',
'%sNo bookings found%s for this search' => '%sKeine Buchungen%s für diese Suche gefunden',
'%sNo events found%s for this search' => '%sKeine Veranstaltungen%s für diese Suche gefunden',
'New user' => 'Neuer Benutzer',
'New booking' => 'Neue Buchung',
'New event' => 'Neue Veranstaltung',
'User has been saved' => 'Benutzer wurde gespeichert',
'User has been deleted' => 'Benutzer wurde gelöscht',
'Booking has been saved' => 'Buchung wurde gespeichert',
'Booking has been deleted' => 'Buchung wurde gelöscht',
'Booking has been cancelled' => 'Buchung wurde storniert',
'Reservation has been deleted' => 'Reservierung wurde gelöscht',
'Event has been saved' => 'Veranstaltung wurde gespeichert',
'Event has been deleted' => 'Veranstaltung wurde gelöscht',
'Square has been saved' => 'Platz wurde gespeichert',
'Square has been deleted' => 'Platz wurde gelöscht',
'User status has been set to deleted' => 'Benutzerstatus wurde auf gelöscht gesetzt',
'Edit' => 'Bearbeiten',
'Save' => 'Speichern',
'Save and back' => 'Speichern und zurück',
'Delete' => 'Löschen',
'Edit user' => 'Benutzer bearbeiten',
'No.' => 'Nr.',
'Notes' => 'Notizen',
'Arbitrary name or identifier for this user' => 'Beliebiger Name oder Bezeichnung',
'Privileges' => 'Berechtigungen',
'Press CTRL to select multiple items' => 'Wenn Sie STRG gedrückt halten, können Sie mehrere Einträge auswählen',
'Please type a name here' => 'Bitte geben Sie hier einen Namen ein',
'Please type a number here' => 'Bitte geben Sie hier eine Zahl ein',
'Please type something here' => 'Bitte geben Sie hier etwas ein',
'Please type more characters here' => 'Bitte geben Sie hier mehr Zeichen ein',
'Please provide the time in format HH:MM' => 'Bitte geben Sie die Zeit in der Form SS:MM ein',
'Active' => 'Aktiv',
'Last activity' => 'Zuletzt aktiv',
'Last IP' => 'Letzte IP',
'Created' => 'Erstellt',
'Created by' => 'Erstellt von',
'Are you sure you want to delete this user?' => 'Sind Sie sicher, dass Sie diesen Benutzer löschen möchten?',
'Yes, delete this user' => 'Ja, Benutzer löschen',
'Delete user' => 'Benutzer löschen',
'Since this user has already bookings, he will be set to deleted but kept in the database'
=> 'Da dieser Benutzer bereits Buchungen hat, wird er auf gelöscht gestellt, bleibt aber in der Datenbank',
'Delete this booking' => 'Buchung löschen',
'Are you sure you want to delete this booking?' => 'Sind Sie sicher, dass Sie diese Buchung löschen möchten?',
'Yes, delete this booking' => 'Ja, Buchung löschen',
'Are you sure you want to delete this reservation?' => 'Sind Sie sicher, dass Sie diese Reservierung löschen möchten?',
'Yes, delete this reservation' => 'Ja, Reservierung löschen',
'Are you sure you want to delete this square?' => 'Sind Sie sicher, dass Sie diesen Platz löschen möchten?',
'Yes, delete this square' => 'Ja, Platz löschen',
'Since this square has already bookings, it will be set to disabled but kept in the database'
=> 'Da es bereits Buchungen für diesen Platz gibt, wird er auf deaktiviert gestellt, bleibt aber in der Datenbank',
'Are you sure you want to delete this product?' => 'Sind Sie sicher, dass Sie dieses Produkt löschen möchten?',
'Yes, delete this product' => 'Ja, Produkt löschen',
'If this booking is cancelled, it will disappear from the calendar, but remain in the database.'
=> 'Wenn diese Buchung storniert wird, verschwindet sie zwar vom Kalender, bleibt aber in der Datenbank erhalten.',
'The booking itself will not be changed. Only the reservation at this date will be deleted.'
=> 'Die Buchung bleibt erhalten, es wird nur diese eine Reservierung gelöscht.',
'This booking consists of multiple reservations:' => 'Diese Buchung besteht aus mehreren Reservierungen:',
'What do you want to edit?' => 'Was möchten Sie bearbeiten?',
'Only this one reservation' => 'Nur diese eine Reservierung',
'The entire booking' => 'Die gesamte Buchung',
'Delete this event' => 'Veranstaltung löschen',
'Are you sure you want to delete this event?' => 'Sind Sie sicher, dass Sie diese Veranstaltung löschen möchten?',
'Yes, delete this event' => 'Ja, Veranstaltung löschen',
'You can use filters like these to narrow your search:' => 'Sie können Filter einsetzen um Ihre Suche einzuschränken:',
'You can also combine a search term and multiple filters like this:'
=> 'Sie können Suchbegriff und Filter auch kombinieren:',
'User ID' => 'Benutzer ID',
'Square ID' => 'Platz ID',
'[custom]' => '[eigene]',
'Users total' => 'Benutzer insgesamt',
'Placeholders total' => 'Platzhalter insgesamt',
'Names and text' => 'Namen und Texte',
'Names and text have been saved' => 'Namen und Texte wurden gespeichert',
'What is the name of your service? What is your name?' => 'Wie ist der Name Ihres Angebotes? Wie ist Ihr Name als Betreiber?',
'Info page' => 'Infoseite',
'Info page has been saved' => 'Infoseite wurde gespeichert',
'Info page text is too short' => 'Der Text der Infoseite ist zu kurz',
'Which text should appear on the info page (%s)?' => 'Welcher Text soll auf der Infoseite (%s) erscheinen?',
'Help page' => 'Hilfeseite',
'Help page has been saved' => 'Hilfeseite wurde gespeichert',
'Help page text is too short' => 'Der Text der Hilfeseite ist zu kurz',
'Which text should appear on the help page?' => 'Welcher Text soll auf der Hilfeseite erscheinen?',
'Which %s do you have? What are their names?' => 'Welche %s haben Sie? Wie sollen diese heißen?',
'Pricing' => 'Preise',
'Pricing rules' => 'Preisregeln',
'Pricing rules have been saved' => 'Preisregeln wurden gespeichert',
'Unknown pricing rules error' => 'Unbekannter Fehler mit den Preisregeln',
'How much do bookings cost for your %s?' => 'Wie teuer sind die Buchungen für Ihre %s?',
'Products' => 'Produkte',
'Which additional products or services do you offer with your bookings?'
=> 'Welche zusätzlichen Produkte oder Dienstleistungen bieten Sie zu Buchungen an?',
'Behaviour' => 'Verhalten',
'How does registration work? How many days are displayed in the calendar?'
=> 'Wie soll die Registrierung ablaufen? Wieviele Tage möchten Sie im Kalender anzeigen?',
'To provide language dependent content here, simply switch the global system language.'
=> 'Wenn Sie die Sprache umstellen (oben rechts) können Sie hier auch sprachabhängige Eingaben machen.',
'New %s' => 'Neuen %s',
'New product' => 'Neues Produkt',
'Price' => 'Preis',
'Price per item' => 'Preis pro Stück',
'All %s' => 'Alle %s',
'All squares' => 'Alle Plätze',
'All' => 'Alle',
'Edit square info and rule texts' => 'Platzinfos und -regeln bearbeiten',
'Current file:' => 'Aktuelle Datei:',
'The name should be at least %min% characters long' => 'Der Name sollte min. %min% Zeichen lang sein',
'The name must not be numeric' => 'Der Name darf nicht nur aus Zahlen bestehen',
'This %s has multiple reservations here:' => 'Dieser %s ist hier mehrfach belegt:',
'Booking created' => 'Buchung erstellt',
'Booking created: %s' => 'Buchung erstellt: %s',
'Booking created: %s by %s' => 'Buchung erstellt: %s von %s',
'Booking cancelled: %s by %s' => 'Buchung storniert: %s von %s',
'Admin users can only be edited by admins' => 'Verwaltungskonten können nur von anderen Verwaltungskonten bearbeitet werden',
'Admin status can only be given by admins' => 'Verwaltungsstatus kann nur von anderen Verwaltungskonten gegeben werden',
'Privileges can only be edited by admins' => 'Berechtigungen können nur von Verwaltungskonten bearbeitet werden',
'These are only visible for administration' => 'Nur für die Verwaltung sichtbar',
'Billing status' => 'Rechnungsstatus',
'Billing total' => 'Rechnungssumme',
'Billing status options' => 'Rechnungsstatus-Bezeichnungen',
'Number of players' => 'Anzahl Spieler',
'Booked to' => 'Gebucht auf',
'Edit user once saved' => 'Benutzer anschließend bearbeiten',
'Edit booking bills once saved' => 'Rechnung anschließend bearbeiten',
'Date (Start)' => 'Datum (Start)',
'Date (End)' => 'Datum (Ende)',
'Time (Start)' => 'Uhrzeit (Start)',
'Time (End)' => 'Uhrzeit (Ende)',
'Clock' => 'Uhr',
'Repeat' => 'Wiederholung',
'Edit time or date range' => 'Zeitraum bearbeiten',
'Time and date range can only be edited on subscription bookings' => 'Der Zeitraum kann nur bei Abo-Buchungen bearbeitet werden',
'Change the time range of all unmodified reservations of this booking:' => 'Uhrzeiten aller unveränderten Reservierungen dieser Buchung ändern:',
'Change the date range and/or interval of this booking:' => 'Zeitraum und/oder Wiederholungsinterval dieser Buchung ändern:',
'Invalid date' => 'Ungültiges Datum',
'Essentially disables the system for the public, but allows administrators to still login'
=> 'Hiermit kann das System in den Wartungsmodus versetzt werden. Im Wartungsmodus ist der Kalender nicht mehr sichtbar und außer Ihnen kann sich niemand anmelden',
'Message' => 'Mitteilung',
'This message optionally appears in maintenance mode' => 'Diese Nachricht erscheint optional im Wartungsmodus',
'This message optionally appears when registration is disabled' => 'Diese Nachricht erscheint optional bei deaktivierter Registrierung',
'Sets if new users are allowed to register' => 'Legt fest, ob sich neue Besucher registrieren, also ein eigenes Konto anlegen dürfen',
'Immediately' => 'Sofort',
'Manually (per backend)' => 'Per Verwaltung (manuell)',
'Automatically (per email)' => 'Per E-Mail (automatisch)',
'Sets how new users are activated after registration' => 'Legt fest, wie neue Benutzer aktiviert werden sollen',
'Days in calendar' => 'Tage im Kalender',
'Sets how many days are displayed in the calendar' => 'Legt fest, wieviele Tage im Kalender gleichzeitig angezeigt werden sollen',
'Hide these days' => 'Folgende Tage verstecken',
'Day names (like Sunday) or concrete dates (like 2016-08-16]; Separated by line breaks or commas; Force concrete dates to be shown by adding a plus (like +2016-08-30)'
=> 'Name des Tages (z. B. Sonntag) oder konkrete Datumangaben (z. B. 16.08.2016]; Getrennt durch Zeilenumbrüche oder Kommata; Ein versteckter Tag kann mit einem Plus wieder angezeigt werden (z. B. +30.08.2016)',
'Your name' => 'Ihr Name',
'Will be shown as the operator of this site. Displayed next to the logo, for example.'
=> 'Wird Ihren Besuchern als Betreiber angezeigt. Erscheint z. B. ganz oben neben dem Logo.',
'Your abbreviation' => 'Ihr Kürzel',
'Short form or abbreviation of your name. Displayed in emails, for example.'
=> 'Kurzform, Abkürzung oder Akronym Ihres Namens. Erscheint z. B. in der Betreffzeile von E-Mails.',
'Your email address' => 'Ihre E-Mail Adresse',
'Will be used for system notifications. Might also be displayed to users for help.'
=> 'Wird für Benachrichtigungen des Systems benötigt. Kann auch Benutzern für Hilfe angezeigt werden.',
'Send user emails like booking/cancel confirmation to this address as well'
=> 'Sende Benutzer-E-Mails wie Buchungs- oder Stornierungsbestätigungen als Kopie an diese Adresse',
'Your phone number' => 'Ihre Telefonnummer',
'Displayed for booking by phone.'
=> 'Wird für die telefonische Buchung angezeigt. Erscheint z. B. ganz oben in der Kopfleiste.',
'Your website' => 'Ihre Webseite',
'The address of your website. Displayed in the header, for example.'
=> 'Die Internetadresse Ihrer Webseite. Erscheint z. B. ganz oben in der Kopfleiste.',
'Your contact page' => 'Ihre Kontaktseite',
'The address of your website\'s contact page. Displayed in the header, for example.'
=> 'Die Internetadresse Ihrer Kontaktseite. Erscheint z. B. ganz oben in der Kopfleiste.',
'Your imprint page' => 'Ihr Impressum',
'Your privacy policy page' => 'Ihre Datenschutzerklärung',
'The address of your website\'s imprint page.' => 'Die Internetadresse Ihres Impressums.',
'The address of your website\'s privacy policy page.' => 'Die Internetadresse Ihrer Datenschutzerklärung.',
'Name of the system' => 'Name des Systems',
'Bookingsystem' => 'Buchungssystem',
'The system presents itself under this name. Displayed next to the logo, for example.'
=> 'Unter diesem Namen präsentiert sich das System. Erscheint z. B. ganz oben neben dem Logo.',
'System abbreviation' => 'Kürzel des Systems',
'Short form or abbreviation of the system name. Displayed in emails, for example.'
=> 'Kurzform, Abkürzung oder Akronym des System-Namens. Erscheint z. B. in der Betreffzeile von E-Mails.',
'Description of your service' => 'Beschreibung Ihres Angebotes',
'One or two short sentences recommended.' => 'Am besten ein bis zwei Sätze über Ihr Angebot.',
'Notation of your "squares"' => 'Bezeichnung Ihrer "Plätze"',
'Notation of your "players"' => 'Bezeichnung Ihrer "Spieler"',
'Name of your facility' => 'Name Ihrer Anlage',
'our Facility' => 'unsere Anlage',
'Displayed in the header, for example. Must start with a lower cased noun marker.'
=> 'Erscheint z. B. in der Kopfleiste. Bitte mit kleinem Artikelwort beginnen.',
'Optional message when readonly' => 'Optionale Nachricht wenn schreibgeschützt',
'Priority' => 'Priorität',
'Capacity' => 'Kapazität',
'How many players fit into one square?' => 'Wieviele Spieler passen auf einen Platz?',
'Don\'t ask for other player\'s names' => 'Nicht nach den Namen der anderen Spieler fragen',
'Ask for other player\'s names (optional)' => 'Nach den Namen der anderen Spieler fragen (optional)',
'Ask for other player\'s names and email address (optional)' => 'Nach den Namen (und E-Mail Adresse) der anderen Spieler fragen (optional)',
'Ask for other player\'s names and phone number (optional)' => 'Nach den Namen (und Telefonnummer) der anderen Spieler fragen (optional)',
'Ask for other player\'s names, email address and phone number (optional)' => 'Nach den Namen (und E-Mail Adresse und Telefonnummer) der anderen Spieler fragen (optional)',
'Ask for other player\'s names (required)' => 'Nach den Namen der anderen Spieler fragen (verpflichtend)',
'Ask for other player\'s names and email address (required)' => 'Nach den Namen (und E-Mail Adresse) der anderen Spieler fragen (verpflichtend)',
'Ask for other player\'s names and phone number (required)' => 'Nach den Namen (und Telefonnummer) der anderen Spieler fragen (verpflichtend)',
'Ask for other player\'s names, email address and phone number (required)' => 'Nach den Namen (und E-Mail Adresse und Telefonnummer) der anderen Spieler fragen (verpflichtend)',
'Multiple bookings' => 'Mehrfachbuchungen',
'May this square be booked multiple times until its full?'
=> 'Kann dieser Platz mehrmals gebucht werden bis er voll ist (s. Kapazität)?',
'Visibility of names' => 'Sichtbarkeit von Namen',
'For other users that are logged in' => 'Für andere angemeldete Benutzer',
'Publicly for everyone' => 'Für alle Besucher öffentlich',
'Who should see the names of the booking users in the calendar?'
=> 'Wer darf die Namen der gebuchten Spieler im Kalender sehen?',
'Time block' => 'Zeitblock',
'Time block (min. bookable)' => 'Zeitblock (min. buchbar)',
'Allow min. bookable time block for admins only' => 'Erlaube min. buchbaren Zeitblock nur für die Verwaltung',
'Users still can only book the normal time blocks then' => 'Benutzer können dann trotzdem nur den normalen Zeitblock buchen',
'Time block (max. bookable)' => 'Zeitblock (max. buchbar)',
'Booking range' => 'Buchung im Voraus',
'How many days in advance can squares be booked?' => 'Wie viele Tage im Voraus kann max. gebucht werden?',
'Cancel range' => 'Stornierung',
'Until when may bookings be cancelled? Set to 0 to never allow. Set to 0.01 for some seconds (practically always).'
=> 'Bis wann darf spätestens storniert werden? Auf 0 setzen, um Stornierungen generell zu verbieten. Auf 0.01 setzen, um praktisch immer stornieren zu können.',
'Label for free squares' => 'Bezeichnung freier Plätze',
'Custom label for free squares in the calendar; default is Free' => 'Individuelle Bezeichnung freier Plätze im Kalender; Standard ist Frei',
'Info (top)' => 'Info (oben)',
'Optional info text, that will be displayed above square details'
=> 'Optionaler Infotext, der über den Platzdetails angezeigt wird',
'Info (bottom)' => 'Info (unten)',
'Optional info text, that will be displayed beneath square details'
=> 'Optionaler Infotext, der unter den Platzdetails angezeigt wird',
'Rules' => 'Regeln',
'Optional rules that must be accepted prior to booking'
=> 'Optionale Regeln, die vor der Buchung akzeptiert werden müssen',
'Rules (file)' => 'Regeln (Datei)',
'Optional rules as PDF-Document that must be accepted prior to booking'
=> 'Optionale Regeln als PDF-Datei, die vor der Buchung akzeptiert werden müssen',
'Rules (file name)' => 'Regeln (Dateiname)',
'Optional file name of the PDF-Document above' => 'Optionaler Name der o.g. PDF-Datei',
'Description' => 'Beschreibung',
'Optional description of this product' => 'Optionale Beschreibung dieses Produktes',
'Options' => 'Optionen',
'Amount of products to choose from, e.g. 1,2,3 to choose between 1 and 3 items'
=> 'Auswahlmöglichkeiten der Anzahl dieses Produktes, z. B. 1,2,3 um zwischen 1 und 3 Stück zu wählen',
'New price' => 'Neuer Preis',
'New time' => 'Neue Zeit',
'New day' => 'Neuer Wochentag',
'New period' => 'Neuer Zeitraum',
'Display pricing:' => 'Preise anzeigen:',
'For no one' => 'Für niemanden',
'For users' => 'Für angemeldete Benutzer',
'For users and visitors' => 'Für Benutzer und Besucher',
'Optionally set a date from when this product will be available. Determined from the booked date.'
=> 'Optionales Datum, ab welchem das Produkt verfügbar sein soll. Bezieht sich auf das gebuchte Datum.',
'Optionally set a date until this product will be available. Determined from the booked date.'
=> 'Optionales Datum, bis zu welchem das Produkt verfügbar sein soll. Bezieht sich auf das gebuchte Datum.',
'Language' => 'Sprache',
'All languages' => 'Alle Sprachen',
'Displays this product only to this language' => 'Zeigt dieses Produkt nur bei dieser Sprache an',
'Edit business terms and privacy policy' => 'AGB und Datenschutzerklärung bearbeiten',
'Edit billing status names and colors' => 'Rechnungsstatus-Bezeichnungen und -Farben bearbeiten',
'Edit Booking-Bill' => 'Buchungs-Rechnung bearbeiten',
'Edit bill' => 'Rechnung bearbeiten',
'Business terms (file)' => 'AGB (Datei)',
'Business terms (file name)' => 'AGB (Dateiname)',
'Privacy policy (file)' => 'Datenschutzerklärung (Datei)',
'Privacy policy (file name)' => 'Datenschutzerklärung (Dateiname)',
'Optional business terms as PDF-Document that must be accepted prior to registration'
=> 'Optionale AGB als PDF-Datei, die vor der Registrierung akzeptiert werden müssen',
'Optional privacy policy as PDF-Document that must be accepted prior to registration'
=> 'Optionale Datenschutzerklärung als PDF-Datei, die vor der Registrierung akzeptiert werden muss',
'How many people can participate?' => 'Wieviele Personen können teilnehmen?',
'There are multiple events for this date and time:' => 'Es gibt mehrere Veranstaltungen für diesen Zeitraum:',
"Pending (pending)\nPaid (paid)\nCancelled (cancelled)\nUncollectable (uncollectable)"
=> "Ausstehend (pending)\nBezahlt (paid)\nStorniert (cancelled)\nUneinbringlich (uncollectable)",
'One status option per line and formatted as either: Name Name (internal value) Name (internal value) Color Name Color
For example: Open (pending) #F00 Paid at place #F00
The following values must exist once: pending, paid, cancelled, uncollectable'
=> 'Ein Wert pro Zeile in einem der folgenden Formate: Name Name (interne Bezeichnung) Name (interne Bezeichnung) Farbe Name Farbe
Zum Beispiel: Offen (pending) #F00 Vor Ort bezahlt #F00
Die folgenden internen Bezeichnungen müssen vorkommen: pending, paid, cancelled, uncollectable',
'Invalid billing status selected' => 'Ungültigen Rechnungsstatus ausgewählt',
'Booking-Bill has been saved' => 'Buchungs-Rechnung wurde gespeichert',
'Booking-Bill position has been created' => 'Buchungs-Rechnungsposten wurde erstellt',
'No Booking-Bill position has been created' => 'Es wurde kein Buchungs-Rechnungsposten erstellt',
'Booking-Bill position has been deleted' => 'Buchungs-Rechnungsposten wurde gelöscht',
'Time (in minutes)' => 'Zeit (in Minuten)',
'Price (in cent)' => 'Preis (in Cent)',
'New position' => 'Neue Position',
'New position by using the pricing rules for this booking' => 'Neue Position durch Anwenden der Preis-Regeln auf diese Buchung',
'Who?' => 'Wer?',
'Player\'s names' => 'Spielernamen',
'Booked by' => 'Gebucht von',
'User matched by' => 'Benutzer ermittelt nach',
];
================================================
FILE: data/res/i18n/de-DE/base.php
================================================
'Zurück zu',
'Related pages' => 'Verwandte Seiten',
' by %s' => ' um %s',
' at %s' => ' um %s',
'On %s' => 'Am %s',
'On last %s' => 'Am letzten %s',
'On next %s' => 'Am nächsten %s',
'Tomorrow' => 'Morgen',
'Yesterday' => 'Gestern',
'%s hours ago' => 'Vor %s Stunden',
'In %s hours' => 'In %s Stunden',
'One hour ago' => 'Vor einer Stunde',
'In one hour' => 'In einer Stunde',
'%s minutes ago' => 'Vor %s Minuten',
'In %s minutes' => 'In %s Minuten',
'One minute ago' => 'Vor einer Minute',
'In one minute' => 'In einer Minute',
'Now' => 'Jetzt',
'Monday' => 'Montag',
'Tuesday' => 'Dienstag',
'Wednesday' => 'Mittwoch',
'Thursday' => 'Donnerstag',
'Friday' => 'Freitag',
'Saturday' => 'Samstag',
'Sunday' => 'Sonntag',
'Second' => 'Sekunde',
'Seconds' => 'Sekunden',
'Minute' => 'Minute',
'Minutes' => 'Minuten',
'Hour' => 'Stunde',
'Hours' => 'Stunden',
'Day' => 'Tag',
'Days' => 'Tage',
'Calendar' => 'Kalender',
'from %s to %s' => 'von %s bis %s',
'from' => 'von',
'%s to %s' => '%s bis %s',
'to' => 'bis',
'and' => 'und',
'or' => 'oder',
'for' => 'für',
'Y-m-d' => 'd.m.Y',
'Page not found' => 'Seite nicht gefunden',
'Oops ... something went wrong here' => 'Oops ... da ist wohl etwas schief gelaufen',
'This page does not (yet) exist' => 'Diese Seite gibt es (noch) nicht',
'Please %sdrop us a note%s if you were expecting this page.'
=> 'Bitte %sinformieren Sie uns%s über dieses Problem, wenn Sie der Meinung sind, dass diese Seite existieren müsste.',
'Back to front page' => 'Zurück zur Startseite',
'Error' => 'Fehler',
'Please %sdrop us a note%s in case of unexpected error messages, %s so that we can repair them quickly.'
=> 'Bitte %sinformieren Sie uns%s bei exotischen oder nicht nachvollziehbaren Fehlermeldungen, %s damit wir das Problem schnell beheben können.',
'Powered by %s' => 'Angetrieben von %s',
'Do your like our service?' => 'Gefällt Ihnen unser Angebot?',
'Contact & Feedback' => 'Kontakt & Feedback',
'Our website' => 'Unsere Internetseite',
'Information about' => 'Infos & Bilder über',
'Book by phone' => 'Telefonische Buchung',
'Imprint' => 'Impressum',
'Privacy' => 'Datenschutz',
'You need to activate %sJavaScript%s in you web browser to proceed. If in doubt, switch to another web browser (e.g. Mozilla Firefox).'
=> 'Sie müssen %sJavaScript%s in Ihrem Webbrowser aktivieren, um fortzufahren. %s Im Zweifel benutzen Sie bitte einen anderen Webbrowser (z. B. Mozilla Firefox).',
'Square' => 'Platz',
'Squares' => 'Plätze',
'Player' => 'Spieler',
'Players' => 'Spieler',
'Visibility' => 'Sichtbarkeit',
'Quantity' => 'Anzahl',
];
================================================
FILE: data/res/i18n/de-DE/booking.php
================================================
'Buchung',
'%s-Booking' => '%s-Buchung',
'Single' => 'Einzelbuchung',
'Subscription' => 'Abo',
'Cancelled' => 'Storniert',
'Pending' => 'Ausstehend',
'Paid' => 'Bezahlt',
'Uncollectable' => 'Uneinbringlich',
'Public' => 'Sichtbar',
'Private' => 'Unsichtbar',
'Only once' => 'Einmalig',
'Daily' => 'Täglich',
'Every 2 days' => 'Alle 2 Tage',
'Every 3 days' => 'Alle 3 Tage',
'Every 4 days' => 'Alle 4 Tage',
'Every 5 days' => 'Alle 5 Tage',
'Every 6 days' => 'Alle 6 Tage',
'Weekly' => 'Wöchentlich',
'Every 2 weeks' => 'Alle 2 Wochen',
'Monthly' => 'Monatlich',
'Ambiguous user name "%s" passed (multiple users under this name)'
=> 'Es gibt mehrere Benutzer mit dem Namen "%s"',
'This booking does not exist' => 'Diese Buchung gibt es nicht',
'This reservation does not exist' => 'Diese Reservierung gibt es nicht',
'Your %s-booking for %s' => 'Ihre %s-Buchung am %s',
'we have reserved %s %s, %s for you. Thank you for your booking.'
=> 'wir haben %s %s am %s für Sie reserviert. Vielen Dank für Ihre Buchung.',
'we have just cancelled %s %s, %s for you.'
=> 'wir haben Ihre Buchung für %s %s, %s storniert.',
'%s\'s %s-booking for %s' => '%s\'s %s-Buchung am %s',
'%s\'s %s-booking has been cancelled' => '%s\'s %s-Buchung wurde storniert',
];
================================================
FILE: data/res/i18n/de-DE/calendar.php
================================================
'Dieses Kalenderdatum ist ungültig',
'The passed calendar squares are invalid' => 'Diese Kalenderanzeige ist ungültig',
'Morning' => 'Morgens',
'Afternoon' => 'Nachmittags',
'Past' => 'Vorbei',
'Too far' => 'Zu fern',
'Closed' => 'Geschlossen',
'Free' => 'Frei',
'Still free' => 'Noch frei',
'Conflict' => 'Konflikt',
'Occupied' => 'Belegt',
'Your Booking' => 'Ihre Buchung',
'Loading' => 'Wird geladen',
'Please wait' => 'Bitte warten',
'Arrival' => 'Anreise',
'Departure' => 'Abreise',
'Our %s for the time' => 'Unsere %s für den Zeitraum',
'Invalid date choice' => 'Ungültige Auswahl',
'Persons' => 'Personen',
];
================================================
FILE: data/res/i18n/de-DE/frontend.php
================================================
'Heute',
'Date' => 'Datum',
'Time' => 'Zeit',
'Show' => 'Anzeigen',
'To book %s, %splease register first%s' => 'Um %s zu buchen, %sregistrieren Sie sich bitte%s',
'or simply %s login here' => 'oder melden %s Sie sich an',
'Email address' => 'E-Mail Adresse',
'Email' => 'E-Mail',
'Phone' => 'Tel.',
'Password' => 'Passwort',
'Login' => 'Anmelden',
'Logout' => 'Abmelden',
'New password' => 'Neues Passwort',
'Get additional %shelp and information%s' => 'Hier erhalten Sie zusätzliche %sHilfe und Infos%s',
'Online as %s' => 'Angemeldet als %s',
'Administration' => 'Verwaltung',
'My bookings' => 'Meine Buchungen',
'My account' => 'Meine Daten',
];
================================================
FILE: data/res/i18n/de-DE/service.php
================================================
'Status des Systems',
'Maintenance' => 'Wartungsarbeiten',
'Help' => 'Hilfe',
'We are currently working on this page.' => 'Diese Seite ist leider noch nicht fertig.',
'The system is currently not available' => 'Das System ist derzeit nicht verfügbar',
'System maintenance underway' => 'Es finden gerade Wartungsarbeiten statt',
'We are back as fast as we can. Promised!' => 'Wir sind so schnell wie möglich wieder für Sie da!',
'The system is available' => 'Das System ist verfügbar',
];
================================================
FILE: data/res/i18n/de-DE/setup.php
================================================
'ep-3 Buchungssystem',
'ep-3 Bookingsystem Setup' => 'ep-3 Buchungssystem Einrichtung',
'imgs/branding/ep3-bs-neg-en.png' => 'imgs/branding/ep3-bs-neg-de.png',
];
================================================
FILE: data/res/i18n/de-DE/square.php
================================================
'Dieser %s ist bereits belegt',
'%sNote:%s Please read and accept the "%s".' => '%sHinweis:%s Bitte lesen und akzeptieren Sie die "%s".',
'%sNote:%s Please read and accept our rules and notes.' => '%sHinweis:%s Bitte lesen und akzeptieren Sie unsere Regeln und Hinweise.',
'%We are sorry:%s This did not work somehow. Please try again.'
=> '%sEntschuldigung:%s Das hat irgendwie nicht funktioniert. Bitte versuchen Sie es erneut.',
'%sCongratulations:%s Your %s has been booked!' => '%sHerzlichen Glückwunsch:%s Ihr %s wurde für Sie gebucht.',
'This booking cannot be cancelled anymore online.' => 'Diese Buchung kann nicht mehr storniert werden.',
'Your booking has been %scancelled%s.' => 'Ihre Buchung wurde %sstorniert%s.',
'Your %s-booking has been cancelled' => 'Ihre %s-Buchung wurde storniert',
'Disabled' => 'Deaktiviert',
'Read-Only' => 'Schreibgeschützt',
'Enabled' => 'Aktiviert',
'Unknown' => 'Unbekannt',
'This square does not exist' => 'Diesen Platz gibt es nicht',
'This square is currently not available' => 'Dieser Platz ist derzeit nicht verfügbar',
'The passed start date is invalid' => 'Dieses Startdatum ist ungültig',
'The passed end date is invalid' => 'Dieses Enddatum ist ungültig',
'The passed start time is invalid' => 'Diese Startzeit ist ungültig',
'The passed end time is invalid' => 'Diese Endzeit ist ungültig',
'The passed time range is invalid' => 'Dieser Zeitraum ist ungültig',
'The passed time is already over' => 'Das ist bereits vorbei',
'The passed date is still too far away' => 'Dieses Datum liegt noch zu weit in der Ferne',
'You cannot book more than %s minutes at once' => 'Sie können nicht mehr als %s Minuten zusammen buchen',
'You have no permission to cancel this booking' => 'Sie dürfen diese Buchung nicht stornieren',
'You have no permission to cancel this subscription' => 'Sie dürfen dieses Abo nicht stornieren',
'This booking does not contain any distinct reservations' => 'Diese Buchung enthält keine Reservierungen',
'This booking does contain multiple distinct reservations (please contact our support)'
=> 'Diese Buchung enthält mehrere einzelne Reservierungen',
'incl.' => 'inkl.',
'including' => 'inkl.',
'plus' => 'zzgl.',
'VAT' => 'USt',
'Summary of your booking:' => 'Übersicht über Ihre Buchung:',
'%s items' => '%s Stück',
'Total' => 'Gesamt',
'Update' => 'Aktualisieren',
'Please note' => 'Bitte beachten',
'Rules-document' => 'Regelwerk',
'this will open in a new window' => 'öffnet in neuem Fenster',
'Yes, I have %1$sread and accepted%2$s the "%3$s"' => 'Ja, ich habe die "%3$s" %1$sgelesen und akzeptiert%2$s',
'Yes, I have %sread and accepted%s these rules and notes' => 'Ja, ich habe die Regeln und Hinweise %sgelesen und akzeptiert%s',
'Your booking will be binding.' => 'Ihre Buchung ist verbindlich.',
'Your booking will be binding, however, you can cancel it up to %s before it takes place.'
=> 'Ihre Buchung ist verbindlich. Sie können sie jedoch bis zu %s vorher stornieren.',
'Complete booking' => 'Buchung abschließen',
'Cancel this booking' => 'Buchung stornieren',
'Cancel booking' => 'Buchung stornieren',
'Are you sure you want to cancel this booking?' => 'Sind Sie sicher, dass Sie diese Buchung stornieren möchten?',
'Yes, cancel this booking' => 'Ja, Buchung stornieren',
'No, go back' => 'Nein, zurück',
'This %s is still free.' => 'Dieser %s ist noch frei.',
'This %s is still free for %s %s.' => 'Dieser %s ist noch frei für %s %s.',
'%s/%s already occupied' => '%s/%s bereits belegt',
'You are going to book this %s.' => 'Sie sind dabei, diesen %s zu buchen.',
'How many %s?' => 'Wie viele %s?',
'Consider our additional offers:' => 'Möglicherweise interessieren Sie sich auch für unsere zusätzlichen Angebote:',
'per item' => 'pro Stück',
'Continue to summary' => 'Weiter zur Übersicht',
'Invalid %s-amount choosen' => 'Ungültige %s-Anzahl ausgewählt',
'Too many %s for this %s choosen' => 'Zu viele %s für diesen %s ausgewählt',
'Bookings for this %s are currently not possible online' => 'Buchungen auf diesem %s sind derzeit nicht online möglich',
'None' => 'Keine',
'Book now' => 'Jetzt buchen',
'Book more' => 'Weitere Buchung',
'You can %slogin%s or %sregister%s, %s to book this %s' => 'Wenn Sie sich %sanmelden%s oder %sregistrieren%s, %s können Sie diesen %s buchen',
'This %s has been %sbooked to you%s.' => 'Dieser %s wurde %sfür Sie gebucht%s.',
'This %s is already occupied.' => 'Dieser %s ist bereits belegt.',
'%s-Check' => '%s-Prüfung',
'Check if your %s is free for your preferred date.' => 'Hier können Sie prüfen, ob Ihr %s zur gewünschten Zeit noch frei ist.',
'Start date' => 'Startdatum',
'End date' => 'Enddatum',
'Check free %s' => 'Auf freie %s prüfen',
'Check' => 'Prüfen',
'You need to activate %sJavaScript%s in your web browser to proceed. If in doubt, switch to another web browser (e.g. Mozilla Firefox).'
=> '%sJavaScript%s muss in Ihrem Webbrowser aktiviert sein um fortzufahren. Im Zweifelsfall benutzen Sie einfach einen anderen Webbrowser (z. B. Mozilla Firefox).',
'until' => 'bis',
'with' => 'mit',
'Change period:' => 'Zeitraum anpassen:',
'Check new period' => 'Neuen Zeitraum prüfen',
'The names of the other players are optional' => 'Die Namen der anderen Spieler sind optional',
'The names of the other players are required' => 'Die Vor- und Nachnamen der anderen Spieler sind erforderlich',
'Player\'s name' => 'Spieler Vor-/Nachname',
'and email address' => 'und E-Mail Adresse',
'and phone number' => 'und Telefonnummer',
];
================================================
FILE: data/res/i18n/de-DE/user.php
================================================
'Sie sind nicht (mehr) angemeldet',
'You have no permission for this' => 'Das dürfen Sie leider nicht',
'Forgot password?' => 'Passwort vergessen?',
'Forgot your password?' => 'Passwort vergessen?',
'We have just received your request to reset your password.' => 'Sie haben kürzlich darum gebeten, Ihr Passwort bei uns neu eingeben zu dürfen.',
'Unfortunately, your account is considered a placeholder and thus cannot login.' => 'Leider wurde Ihr Benutzerkonto als Platzhalter definiert.',
'Unfortunately, your account is currently blocked. Please contact us for support.' => 'Leider wurde Ihr Benutzerkonto gesperrt. Bitte kontaktieren Sie uns.',
'Unfortunately, your account has not yet been activated. If you did not receive an activation email yet, you can request a new one here:'
=> 'Leider wurde Ihr Benutzerkonto noch nicht aktiviert. Wenn Sie bisher noch keine Aktivierungs E-Mail von uns bekommen haben, können Sie sich hier eine neue zusenden lassen:',
'Simply visit the following website to type your new password:' => 'Besuchen Sie einfach nur die folgende Internetseite und geben Ihr neues Passwort ein:',
'However, you are using a privileged account. For safety, you cannot reset your password this way. Please contact the system support.'
=> 'Allerdings besitzen Sie ein Benutzerkonto mit besonderen Rechten. Aus Sicherheitsgründen können Sie Ihr Passwort daher nicht auf diesem Wege ändern. Kontaktieren Sie bitte den Support.',
'Unfortunately, your account seems somewhat unique, thus we are unsure how to treat it. Mind contacting us?'
=> 'Leider haben wir ein paar technische Probleme mit Ihrem Benutzerkonto. Würden Sie uns kontaktieren?',
'All right, you should receive an email from us soon' => 'In Ordnung, Sie sollten in Kürze eine E-Mail von uns erhalten',
'if we find a valid user account with this email address' => 'sofern wir ein gültiges Benutzerkonto zu dieser E-Mail Adresse finden',
'Your token to reset your password is invalid or expired. Please request a new email.'
=> 'Der Code zum Ändern Ihres Passwortes ist ungültig oder abgelaufen. Bitte lassen Sie sich eine neue E-Mail zusenden.',
'All right, your password has been changed. You can now log into your account.'
=> 'In Ordnung, Ihr Passwort wurde geändert. Sie können sich nun wieder anmelden.',
'New registration waiting for activation' => 'Neuer Benutzer wartet auf Aktivierung',
'A new user has registered to your %s. According to your configuration, this user will not be able to book %s until you manually activate him.'
=> 'Ein neuer Benutzer hat sich bei Ihrem %s registriert. Entsprechend Ihrer Einstellungen muss dieser Benutzer manuell aktiviert werden, bevor dieser %s buchen kann.',
'Your registration to the %s %s' => 'Ihre Registrierung beim %s %s',
"welcome to the %s %s!\r\n\r\nThank you for your registration to our service.\r\n\r\nBefore you can completely use your new user account to book spare %s online, you have to activate it by simply clicking the following link. That's all!\r\n\r\n%s"
=> "herzlich Willkommen zum %s %s!\r\n\r\nVielen Dank für Ihre Registrierung für unser Angebot.\r\n\r\nBevor Sie nun freie %s online buchen können, müssen Sie nur noch folgende Internetseite besuchen um Ihr Benutzerkonto zu aktivieren und schon können Sie loslegen!\r\n\r\n%s",
'Your activation code seems invalid. Please try again.' => 'Ihr Aktivierungs-Code scheint ungültig zu sein. Bitte versuchen Sie es erneut.',
'You cannot manually activate your account currently' => 'Sie können Ihr Benutzerkonto derzeit nicht selbst aktivieren',
'We have just received your request for a new user account activation email.' => 'Sie haben kürzlich um eine neue Aktivierungs E-Mail gebeten.',
'Unfortunately, your account is considered a placeholder and thus cannot be activated.' => 'Leider wurde Ihr Benutzerkonto als Platzhalter definiert.',
"Before you can completely use your new user account to book spare %s online, you have to activate it by simply clicking the following link. That's all!\r\n\r\n%s"
=> "Bevor Sie nun freie %s online buchen können, müssen Sie nur noch folgende Internetseite besuchen um Ihr Benutzerkonto zu aktivieren und schon können Sie loslegen!\r\n\r\n%s",
'However, your account has already been activated. You can login whenever you like!'
=> 'Allerdings ist Ihr Benutzerkonto bereits aktiviert. Sie können sich jederzeit anmelden.',
'Your %sphone number%s has been updated' => 'Ihre %sTelefonnummer%s wurde aktualisiert',
'New email address at %s %s' => 'Neue E-Mail Adresse beim %s %s',
"You have just changed your account's email address to this one.\r\n\r\nBefore you can completely use your new email address to book spare %s online again, you have to activate it by simply clicking the following link. That's all!\r\n\r\n%s"
=> "Sie haben kürzlich Ihre E-Mail Adresse bei uns geändert. Bevor Sie nun wieder freie %s online buchen können, müssen Sie folgende Internetseite besuchen um Ihr Benutzerkonto zu aktivieren und schon können Sie loslegen!\r\n\r\n%s",
'Your %semail address%s has been updated' => 'Ihre %sE-Mail Adresse%s wurde aktualisiert',
'Your %snotification settings%s have been updated' => 'Ihre %sBenachrichtigungs-Einstellungen%s wurden aktualisiert',
'Your %spassword%s has been updated' => 'Ihr %sPasswort%s wurde aktualisiert',
'This is not your correct password' => 'Das ist nicht Ihr richtiges Passwort',
'Your %suser account has been deleted%s. Good bye!' => 'Ihr %sBenutzerkonto wurde gelöscht%s. Auf Wiedersehen!',
'Due to too many login attempts, temporarily blocked until %s' => 'Aufgrund zu vieler Anmeldeversuche gesperrt bis %s',
'This account is considered a placeholder and thus cannot login' => 'Leider wurde dieses Benutzerkonto als Platzhalter definiert.',
'Email address and/or password invalid' => 'E-Mail Adresse und/oder Passwort falsch',
'This account is currently blocked' => 'Dieses Benutzerkonto ist derzeit gesperrt',
'This account has not yet been activated' => 'Dieses Benutzerkonto wurde noch nicht aktiviert',
'Welcome, %s' => 'Willkommen, %s',
'User' => 'Benutzer',
'Placeholder' => 'Platzhalter',
'Deleted user' => 'Gelöschter Benutzer',
'Blocked user' => 'Gesperrter Benutzer',
'Waiting for activation' => 'Auf Aktivierung wartend',
'Enabled user' => 'Aktivierter Benutzer',
'Assist' => 'Mitarbeiter',
'Admin' => 'Verwaltung',
'Mr.' => 'Herr',
'Mrs' => 'Frau',
'Family' => 'Familie',
'Firm' => 'Firma',
'May manage users' => 'Darf Benutzer verwalten',
'May manage bookings' => 'Darf Buchungen verwalten',
'May manage events' => 'Darf Veranstaltungen verwalten',
'May change configuration' => 'Darf Einstellungen verändern',
'Can see the admin menu' => 'Sieht das Verwaltungsmenü',
'Can see the past in calendar' => 'Sieht auch vergangene Buchungen',
'Can see names and data in calendar' => 'Sieht Namen und Details im Kalender',
'May create single bookings' => 'Darf Einzelbuchungen erstellen',
'May cancel single bookings' => 'Darf Einzelbuchungen stornieren',
'May delete single bookings' => 'Darf Einzelbuchungen löschen',
'May create multiple bookings' => 'Darf Abos erstellen',
'May cancel multiple bookings' => 'Darf Abos stornieren',
'May delete multiple bookings' => 'Darf Abos löschen',
'Request activation mail' => 'Aktivierungs E-Mail senden',
'Resend activation email' => 'Aktivierung erneut senden',
'Were you not happy with our service? Please tell us why you leave. Thank you!'
=> 'Waren Sie mit unserem Angebot nicht zufrieden? Wir würden uns sehr freuen, wenn Sie uns noch kurz verraten, warum Sie gehen. Vielen Dank!',
'Delete account' => 'Benutzerkonto löschen',
'Your current password' => 'Ihr aktuelles Passwort',
'Your new password' => 'Ihr neues Passwort',
'Please provide your email address' => 'Hiermit melden Sie sich an',
'Please type your email address here' => 'Bitte geben Sie Ihre E-Mail Adresse ein',
'Please type your correct email address here' => 'Bitte geben Sie Ihre richtige E-Mail Adresse ein',
'We could not verify your email provider' => 'Dieser E-Mail Anbieter existiert leider nicht',
'Trash mail addresses are currently blocked - sorry' => 'Wegwerf-E-Mail-Adressen sind derzeit gesperrt',
'This email address has already been registered' => 'Diese E-Mail Adresse wurde bereits registriert',
'Both email addresses must be identical' => 'Die beiden E-Mail Adressen sind verschieden',
'Both passwords must be identical' => 'Die beiden Passwörter sind verschieden',
'Please type your password here' => 'Bitte geben Sie Ihr Passwort ein',
'Please type a new password here' => 'Bitte geben Sie ein neues Passwort ein',
'Please type your email address again to prevent typing errors' => 'Bitte geben Sie Ihre E-Mail Adresse zum Schutz gegen Tippfehler noch einmal ein',
'Please type your password again to prevent typing errors' => 'Bitte geben Sie Ihr Passwort zum Schutz gegen Tippfehler noch einmal ein',
'Please type your new password again to prevent typing errors' => 'Bitte geben Sie Ihr Passwort zum Schutz gegen Tippfehler noch einmal ein',
'Your new password should be at least %min% characters long' => 'Ihr neues Passwort sollte mindestens %min% Zeichen lang sein',
'Notify on bookings and cancellations' => 'Bei Buchungen und Stornierungen',
'We can send you confirmations per email' => 'Wir können Ihnen Buchungen und Stornierungen zusätzlich per E-Mail bestätigen',
'Update phone number' => 'Telefonnummer ändern',
'Update email address' => 'E-Mail Adresse ändern',
'Update settings' => 'Einstellungen ändern',
'Update password' => 'Passwort ändern',
'Change password' => 'Passwort ändern',
'Please type your phone number here' => 'Bitte geben Sie Ihre Telefonnummer ein',
'This phone number is somewhat short ...' => 'Diese Telefonnummer ist etwas kurz',
'This phone number contains invalid characters - sorry' => 'Diese Telefonnummer enthält ungültige Zeichen',
'Your password will be safely encrypted' => 'Ihr Passwort wird sicher verschlüsselt',
'Please type your password again' => 'Bitte geben Sie Ihr Passwort erneut ein',
'We only use this to inform you about changes to your bookings' => 'Wird benötigt, damit wir Sie bei Buchungsänderungen informieren können',
'Salutation' => 'Anrede',
'First & Last name' => 'Vor- & Nachname',
'Last name' => 'Nachname',
'Street & Number' => 'Straße und Hausnummer',
'Street number' => 'Hausnummer',
'Postal code & City' => 'Postleitzahl & Ort',
'City' => 'Wohnort',
'Phone number' => 'Telefonnummer',
'Birthday' => 'Geburtstag',
'This is optional' => 'Diese Angabe ist freiwillig',
'Complete registration' => 'Registrierung abschließen',
'Please type your name here' => 'Bitte geben Sie Ihren Namen ein',
'Your name is somewhat short ...' => 'Dieser Name ist etwas kurz',
'Your name contains invalid characters - sorry' => 'Dieser Name enthält ungültige Zeichen',
'Your last name is somewhat short ...' => 'Dieser Nachname ist etwas kurz',
'Your last name contains invalid characters - sorry' => 'Dieser Nachname enthält ungültige Zeichen',
'Please type your street name here' => 'Bitte geben Sie Ihre Straße ein',
'This street name is somewhat short ...' => 'Dieser Straßenname ist etwas kurz',
'This street name contains invalid characters - sorry' => 'Dieser Straßenname enthält ungültige Zeichen',
'Please type your street number here' => 'Bitte geben Sie Ihre Hausnummer ein',
'This street number contains invalid characters - sorry' => 'Diese Hausnummer enthält ungültige Zeichen',
'Please type your postal code here' => 'Bitte geben Sie Ihre Postleitzahl ein',
'Please provide a correct postal code' => 'Bitte geben Sie eine gültige Postleitzahl ein',
'Please type your city here' => 'Bitte geben Sie Ihren Wohnort ein',
'This city name is somewhat short ...' => 'Dieser Wohnort ist etwas kurz',
'This city name contains invalid characters - sorry' => 'Dieser Wohnort enthält ungültige Zeichen',
'Please leave this field empty' => 'Bitte lassen Sie dieses Feld leer',
'Please register about our website only' => 'Bitte benutzen Sie ausschließlich unser Registrierungs-Formular',
'You were too quick for our system! Please wait some seconds and try again. Thank you!' => 'Sie waren zu schnell für unser System. Bitte warten Sie ein paar Sekunden und versuchen Sie es erneut.',
'User name too short' => 'Benutzername zu kurz',
'This user does not exist' => 'Diesen Benutzer gibt es nicht',
'You have no imminent bookings.' => 'Sie haben keine aktuellen Buchungen.',
'You have not booked any %s yet.' => 'Sie haben noch keine %s gebucht.',
'You have already booked one %s.' => 'Sie haben bereits einen %s gebucht.',
'You have already booked %s %s.' => 'Sie haben bereits %s %s gebucht.',
'If you did not receive an activation email from us after registration, you can request a new one here.'
=> 'Wenn Sie nach der Registrierung keine Aktivierungs E-Mail von uns erhalten haben, können Sie sich hier eine neue zusenden lassen.',
'Therefore, please type the email adress you used for registration.' => 'Geben Sie dazu bitte Ihre E-Mail Adresse ein.',
'Your user account has been activated. You can now login with your email address and password. Have fun!'
=> 'Ihr Benutzerkonto wurde erfolgreich aktiviert. Sie können sich nun anmelden. Viel Spaß!',
'Now you can type a new password for your user account.' => 'Nun können Sie ein neues Passwort für Ihr Benutzerkonto eingeben.',
'No need to be sad. You may simply type your email address here and you will soon be able to choose a new password.'
=> 'Kein Grund traurig zu sein. Geben Sie hier einfach Ihre E-Mail Adresse ein und wir senden Ihnen eine E-Mail zum Zurücksetzen Ihres Passwortes zu.',
'Registration complete' => 'Registrierung abgeschlossen',
'The registration is complete and your user account has been created successfully'
=> 'Die Registrierung ist nun abgeschlossen und Ihr Benutzerkonto wurde erfolgreich erstellt',
'You can now login with your email address and password. Have fun!'
=> 'Sie können sich nun mit Ihrer E-Mail Adresse und Ihrem Passwort anmelden. Viel Spaß!',
'However, your user account is %snot yet activated%s.'
=> 'Allerdings ist Ihr Benutzerkonto %snoch nicht freigeschaltet%s.',
'This will happen during a quick manual verification of your user account data.'
=> 'Dies geschieht nach einer kurzen manuellen Prüfung Ihrer Daten.',
'Please be patient, this will be done soon.'
=> 'Bitte haben Sie etwas Geduld.',
'The only step remaining is to %sactivate your user account%s.'
=> 'Jetzt muss Ihr Benutzerkonto nur noch kurz %saktiviert werden%s.',
'For this, we just sent you an email with an activation link within. Please check.'
=> 'Dazu haben wir Ihnen soeben eine E-Mail gesendet, in welcher Sie einen Aktivierungs-Link finden.',
'If you did not receive an email from us, you can always %srequest a new one%s.'
=> 'Wenn Sie keine E-Mail von uns bekommen, können Sie sich jederzeit %seine neue zusenden lassen%s.',
'Register now' => 'Jetzt registrieren',
'Registration' => 'Registrierung',
'Activation' => 'Aktivierung',
'Welcome to our %s' => 'Willkommen zu unserem %s',
'You probably guessed it: To use our service, that is to book spare %s online, you need to create your own user account first.'
=> 'Sie haben es sicher schon vermutet: Um unser Angebot nutzen zu können, also um freie %s online buchen zu können, müssen Sie sich vorher ein eigenes Benutzerkonto auf Ihren Namen und Ihre E-Mail Adresse erstellen.',
'The registration is of course free of cost and nonbinding.' => 'Die Registrierung ist natürlich kostenlos und unverbindlich.',
'We are very sorry, but the registration is currently not possible.' => 'Entschuldigung, aber die Registrierung ist derzeit nicht möglich.',
'Login data' => 'Zugangsdaten',
'Account data' => 'Zugangsdaten',
'Personal data' => 'Persönliche Angaben',
'I have read and accept the %1$sprivacy policy%2$s' => 'Ich habe die %1$sDatenschutzerklärung%2$s gelesen und akzeptiere diese',
'please inform us about changes, so we can update this data' => 'bitte informieren Sie uns über Änderungen',
'Note: You need to activate your account again if you update your email address.'
=> 'Hinweis: Sie müssen Ihr Benutzerkonto erneut aktivieren, wenn Sie die E-Mail Adresse ändern.',
'Update notifications' => 'Benachrichtigungen',
'Delete this account' => 'Benutzerkonto löschen',
'Bye, %s' => 'Auf Wiedersehen, %s',
'If you have already registered, you can login here with your email address and start booking %s.'
=> 'Wenn Sie sich bereits bei uns registriert haben, können Sie sich hier mit Ihrer E-Mail Adresse anmelden um %s zu buchen.',
'Bill' => 'Rechnung',
'Booking-Bill' => 'Buchungs-Rechnung',
'I agree to %s' => 'Ich habe das Dokument %s gelesen und akzeptiere es',
'Please agree to this' => 'Bitte akzeptieren Sie das',
/* Email */
'Dear' => 'Sehr geehrte/r Herr/Frau',
'Hello' => 'Hallo',
'This was an automated message from the system.' => 'Diese Nachricht wurde automatisch gesendet.',
'Originally sent to %s (%s).' => 'Ursprünglich gesendet an %s (%s).',
'Sincerely' => 'Viele Grüße',
'Your' => 'Ihr',
];
================================================
FILE: data/res/i18n/fr-FR/backend.php
================================================
'Utilisateurs',
'Create, edit or delete the users of your system' => 'Créez, Editez ou supprimez un Utilisateur',
'Bookings' => 'Réservations',
'Create, edit or delete the bookings of your system' => 'Créez, Editez ou supprimez une Réservation',
'Event' => 'Evènement',
'Events' => 'Evènements',
'Create, edit or delete the events of your system' => 'Créez, Editez ou supprimez un Evènements',
'Statistic' => 'Statistiques',
'User-Statistic' => 'Statistiques Utilisateurs',
'Booking-Statistic' => 'Statistiques Réservations',
'Event-Statistic' => 'Statistiques Evènements',
'Configuration' => 'Configuration',
'Configuration has been saved' => 'La Configuration a été sauvée',
'Configuration has been updated' => 'La Configuration a été mise à jour',
'Configuration is (partially) invalid' => 'La Configuration est (en partie) invalide',
'Configure your system just as you need it' => 'Configurez ce système selon vos besoins',
'Here you can configure and fine tune your system just as you need it.'
=> 'Ici vous pouvez configurer le système selon vos besoins.',
'User-Administration' => 'Utilisateurs-Administration',
'Here you can create, edit or delete the users of your system.' => 'Ici vous pouvez créer, éditer ou supprimer des utilisateurs.',
'Booking-Administration' => 'Réservations-Administration',
'Here you can create, edit or delete the bookings of your system.' => 'Ici vous pouvez créer, éditer ou supprimer des réservations.',
'Event-Administration' => 'Evènements-Administration',
'Here you can create, edit or delete the events of your system.' => 'Ici vous pouvez créer, éditer ou supprimer des événements.',
'Name or number' => 'Nom ou numéro',
'Search' => 'Recherche',
'Advanced search' => 'Recherche avancée',
'%sNo users found%s for this search' => '%saucun utilisateur trouvé pour cette recherche',
'%sNo bookings found%s for this search' => '%ssaucune réservation trouvée pour cette recherche',
'%sNo events found%s for this search' => '%ssaucun événement trouvé pour cette recherche',
'New user' => 'Nouvel utilisateur',
'New booking' => 'Nouvelle réservation',
'New event' => 'Nouvel événement',
'User has been saved' => 'Profil sauvegardé',
'User has been deleted' => 'Utilisateur supprimé',
'Booking has been saved' => 'Réservation sauvegardée',
'Booking has been deleted' => 'Réservation supprimée',
'Booking has been cancelled' => 'Réservation annulée',
'Reservation has been deleted' => 'La réservation a été supprimé',
'Event has been saved' => 'Evènement sauvegardé',
'Event has been deleted' => 'Evènement supprimé',
'Square has been saved' => 'Court sauvegardé',
'Square has been deleted' => 'Court supprimé',
'User status has been set to deleted' => '>Statut utilisateur à supprimer',
'Edit' => 'Editer',
'Save' => 'Sauver',
'Save and back' => 'Sauver et revenir',
'Delete' => 'Supprimer',
'Edit user' => 'Editer utilisateur',
'No.' => 'No.',
'Notes' => 'Notes',
'Arbitrary name or identifier for this user' => 'Nom ou identifiant pour cet utilisateur',
'Privileges' => 'Privilèges',
'Press CTRL to select multiple items' => 'Appuyez sur CTRL pour selectionner plusieurs articles',
'Please type a name here' => 'Veuillez saisir un nom ici',
'Please type a number here' => 'Veuillez saisir un numéro ici',
'Please type something here' => 'Veuillez saisir quelque chose ici',
'Please type more characters here' => 'Veuillez saisir plus de caractères ici',
'Please provide the time in format HH:MM' => 'Veuillez saisir l\'heure au format HH:MM',
'Active' => 'Actif',
'Last activity' => 'Dernière activité',
'Last IP' => 'Dernière IP',
'Created' => 'Créé',
'Created by' => 'Créé par',
'Are you sure you want to delete this user?' => 'Êtes-vous certain de vouloir supprimer cet utilisateur ?',
'Yes, delete this user' => 'Oui, supprimer',
'Delete user' => 'Supprimer cet utilisateur',
'Since this user has already bookings, he will be set to deleted but kept in the database'
=> 'Comme cet utilisateur a des réservations, il sera marqué pour suppression mais restera en base de données',
'Delete this booking' => 'Supprimer cette réservation',
'Are you sure you want to delete this booking?' => 'Êtes-vous certain de vouloir supprimer cette réservation ?',
'Yes, delete this booking' => 'Oui, supprimer',
'Are you sure you want to delete this reservation?' => 'Êtes-vous certain de vouloir supprimer cette réservation ?',
'Yes, delete this reservation' => 'Oui, supprimer',
'Are you sure you want to delete this square?' => 'Êtes-vous certain de vouloir supprimer ce court ?',
'Yes, delete this square' => 'Oui, supprimer',
'Since this square has already bookings, it will be set to disabled but kept in the database'
=> 'Comme ce court est réservé, il sera désactivé mais restera en base de données',
'Are you sure you want to delete this product?' => 'Êtes-vous certain de vouloir supprimer ce produits ?',
'Yes, delete this product' => 'Oui, supprimer',
'If this booking is cancelled, it will disappear from the calendar, but remain in the database.'
=> 'Cette réservation est annulée, elle va disparaître du calendrier, mais restera en base de données.',
'The booking itself will not be changed. Only the reservation at this date will be deleted.'
=> 'La réservation en elle-même ne sera pas modifiée. Seule cette date sera effacée.',
'This booking consists of multiple reservations:' => 'Cette réservation contient plusieurs dates:',
'What do you want to edit?' => 'Que voulez-vous éditer ?',
'Only this one reservation' => 'Juste cette date',
'The entire booking' => 'La réservation entière',
'Delete this event' => 'Supprimer cet évènement',
'Are you sure you want to delete this event?' => 'Êtes-vous certain de vouloir supprimer cet évènement ?',
'Yes, delete this event' => 'Oui, supprimer',
'You can use filters like these to narrow your search:' => 'Vous pouvez utiliser des filtres afin de restreindre votre recherche, comme ceci:',
'You can also combine a search term and multiple filters like this:'
=> 'Vous pouvez aussi combiner la recherche textuelle et de multiples filtres, comme ceci:',
'Users total' => 'Total utilisateurs',
'Placeholders total' => 'Placeholders total',
'Names and text' => 'Noms et Textes',
'Names and text have been saved' => 'Nom et Texte sauvegardés',
'What is the name of your service? What is your name?' => 'Quel est le nom de votre service? Quel est votre nom?',
'Info page' => 'Page info',
'Info page has been saved' => 'Page info sauvegardé',
'Info page text is too short' => 'Le texte de la page info est trop court',
'Which text should appear on the info page (%s)?' => 'Quel texte doit apparaître dans la page info (%s)?',
'Help page' => 'Page aide',
'Help page has been saved' => 'Page aide sauvegardé',
'Help page text is too short' => 'Le texte de la page aide est trop court',
'Which text should appear on the help page?' => 'Quel texte doit apparaître dans la page aide?',
'Which %s do you have? What are their names?' => 'De combien de %s disposez-vous? Quels sont leur noms?',
'Pricing' => 'Tarifs',
'Pricing rules' => 'Politiques tarifaires',
'Pricing rules have been saved' => 'Politiques tarifaires sauvegardés',
'Unknown pricing rules error' => 'Erreur: Politique tarifaire inconnue',
'How much do bookings cost for your %s?' => 'Combien la réservation des %s coûte-t\'elle ?',
'Products' => 'Produits',
'Which additional products or services do you offer with your bookings?'
=> 'Quel produit ou service additionnel offrez-vous avec une réservation ?',
'Behaviour' => 'Comportement',
'How does registration work? How many days are displayed in the calendar?'
=> 'Comment fonctionne le processus de réservation ? Combien de jours sont affichés au calendrier ?',
'To provide language dependent content here, simply switch the global system language.'
=> 'Pour créer un contenu multilingue, changez simplement la langue.',
'New %s' => 'Nouveau %s',
'New product' => 'Nouveau Produit',
'Price' => 'Prix',
'Price per item' => 'Prix par article',
'All %s' => 'Tous les %s',
'All squares' => 'Tous les courts',
'All' => 'Tout',
'Edit square info and rule texts' => 'Editez les informations et règles pour ce court',
'Current file:' => 'Fichier actuel:',
'The name should be at least %min% characters long' => 'Le nom doit compté au moins %min% caractères',
'The name must not be numeric' => 'Le nom ne doit pas être numérique',
'This %s has multiple reservations here:' => 'Ce %s a de multiples réservations:',
'Booking created' => 'Réservation créée',
'Booking created: %s' => 'Réservation créée: %s',
'Booking created: %s by %s' => 'Réservation créée: %s par %s',
'Booking cancelled: %s by %s' => 'Réservation annulée: %s par %s',
'Admin users can only be edited by admins' => 'Les comptes administrateurs ne peuvent être éditer que par des administrateurs',
'Admin status can only be given by admins' => 'Le status administrateur ne peut être attribué que par un administrateur',
'Privileges can only be edited by admins' => 'Les privilèges ne peuvent être édités que par des administrateurs',
'These are only visible for administration' => 'Ceci n\'est visible que des administrateurs',
'Billing status' => 'Status de facturation',
'Billing status options' => 'Options des status de facturation',
'Number of players' => 'Nombre de joueurs',
'Booked to' => 'Réservé par',
'Edit user once saved' => 'Editer l\'utilisateur après la sauvegarde',
'Date (Start)' => 'Date (Début)',
'Date (End)' => 'Date (Fin)',
'Time (Start)' => 'Heure (Début)',
'Time (End)' => 'Heure (Fin)',
'Clock' => 'Horloge',
'Repeat' => 'Répéter',
'Edit time or date range' => 'Editer les créneaux horaires',
'Time and date range can only be edited on subscription bookings' => 'Les créneaux horaires ne peuvent être édités qu\'en cas d\'abonnement',
'Change the time range of all unmodified reservations of this booking:' => 'Changer les créneaux horaires de toutes les réservations:',
'Change the date range and/or interval of this booking:' => 'Changer les créneaux horaires et/ou les intervalles de cette réservation:',
'Invalid date' => 'Date invalide',
'Essentially disables the system for the public, but allows administrators to still login'
=> 'Désactve essentiellement le système pour le public. Mais permet aux administrateurs de continuer à ce connecter ',
'Message' => 'Message',
'This message optionally appears in maintenance mode' => 'Ce message apparaît optionnellement en mode maintenance',
'This message optionally appears when registration is disabled' => 'Ce message apparaît optionnellement quand l\'enregistrement est désactivé',
'Sets if new users are allowed to register' => 'Etablit si les nouveaux utilisateurs peuvent s\'enregister',
'Immediately' => 'Immediatement',
'Manually (per backend)' => 'Manuellement (par le back office)',
'Automatically (per email)' => 'Automatiquement (par email)',
'Sets how new users are activated after registration' => 'Etablit si les nouveaux utilisateurs sont actifs directement après l\'enregistrement',
'Days in calendar' => 'Jours dans le calendrier',
'Sets how many days are displayed in the calendar' => 'Etablit combien de Jours sont affichés dans le calendrier',
'Your name' => 'Votre Nom',
'Will be shown as the operator of this site. Displayed next to the logo, for example.'
=> 'Sera présenté comme l\'opérateur de ce site. Affiché à coté du logo, par exemple.',
'Your abbreviation' => 'Abréviation',
'Short form or abbreviation of your name. Displayed in emails, for example.'
=> 'Nom court ou Abréviation. Affiché dans les E-Mails, par exemple.',
'Your email address' => 'Votre adresse E-Mail',
'Will be used for system notifications. Might also be displayed to users for help.'
=> 'Sera utilisée pour les notifications système. Peut aussi être affiché aux utilisateurs pour aide.',
'Send user emails like booking/cancel confirmation to this address as well'
=> 'Envoyer les emails utilisateurs comme les confirmations de réservation/annulation en copie à cette adresse',
'Your phone number' => 'Votre numéro de téléphone',
'Displayed for booking by phone.'
=> 'Affiché dans le cadre des réservations par téléphone.',
'Your website' => 'Votre site web',
'The address of your website. Displayed in the header, for example.'
=> 'L\'adresse de votre site web. Affiché dans la bannière, par exemple.',
'Your contact page' => 'Votre page de contact',
'The address of your website\'s contact page. Displayed in the header, for example.'
=> 'L\'adresse de la page contact de votre site web. Affiché dans la bannière, par exemple.',
'Your imprint page' => 'Votre page pour impression',
'The address of your website\'s imprint page.' => 'L\'adresse de la page impression de votre site web.',
'Name of the system' => 'Nom du système',
'The system presents itself under this name. Displayed next to the logo, for example.'
=> 'Le système se présente sous ce nom. Affiché à côté du logo, par exemple.',
'System abbreviation' => 'Abréviation pour le système',
'Short form or abbreviation of the system name. Displayed in emails, for example.'
=> 'Nom court ou Abréviation pour le système. Affiché dans les E-Mails, par exemple.',
'Description of your service' => 'Description de vos services',
'One or two short sentences recommended.' => 'Une ou deux phrases courtes (recommandé).',
'Notation of your "squares"' => 'Nom pour définir vos "Ressources" (terrains, salles...)',
'Notation of your "players"' => 'Nom pour définir vos "Utilisateurs" (joueurs, intervenants...)',
'Name of your facility' => 'Nom de votre établissement',
'Displayed in the header, for example. Must start with a lower cased noun marker.'
=> 'Affiché dans la bannière, par exemple. Doit commencer par une lettre minuscule.',
'Optional message when readonly' => 'Message optionnel en mode lecture seule',
'Priority' => 'Priorité',
'Capacity' => 'Capacité',
'How many players fit into one square?' => 'Combien de joueurs peuvent utiliser un court ?',
'Don\'t ask for other player\'s names' => 'Ne pas demander le nom des autres joueurs',
'Ask for other player\'s names (optional)' => 'Demander les noms des autres joueurs (optionnel)',
'Ask for other player\'s names and email address (optional)' => 'Demander les noms et adresses eMail des autres joueurs (optionnel)',
'Ask for other player\'s names and phone number (optional)' => 'Demander les noms et numéros de téléphone des autres joueurs (optionnel)',
'Ask for other player\'s names, email address and phone number (optional)' => 'Demander les noms, adresses eMail et numéros de téléphone des autres joueurs (optionnel)',
'Ask for other player\'s names (required)' => 'Demander les noms des autres joueurs (requis)',
'Ask for other player\'s names and email address (required)' => 'Demander les noms et adresses eMail des autres joueurs (requis)',
'Ask for other player\'s names and phone number (required)' => 'Demander les noms et numéros de téléphone des autres joueurs (requis)',
'Ask for other player\'s names, email address and phone number (required)' => 'Demander les noms, adresses eMail et numéros de téléphone des autres joueurs (requis)',
'Multiple bookings' => 'Réservations multiples',
'May this square be booked multiple times until its full?'
=> 'Ce court peut-il être réservé plusieurs fois jusqu\'a ce qu\'il soit plein?',
'Visibility of names' => 'Visibilité des noms',
'For other users that are logged in' => 'Pour les autres utilisateurs connectés',
'Publicly for everyone' => 'Pour tout le monde (publiquement)',
'Who should see the names of the booking users in the calendar?'
=> 'Qui doit voir sur le calendrier les noms des utilisateurs qui ont réservé ?',
'Time block' => 'Bloc de temps',
'Time block (min. bookable)' => 'Bloc de temps (min. réservable)',
'Allow min. bookable time block for admins only' => 'Permettre aux administrateurs seuls de réserver le temps minimum',
'Users still can only book the normal time blocks then' => 'De fait les utilisateurs ne pourront réserver que sur des blocs de temps normaux',
'Time block (max. bookable)' => 'Bloc de temps (max. réservable)',
'Booking range' => 'Réservation à l\'avance',
'How many days in advance can squares be booked?' => 'Combien de jours à l\'avance Les réservations peuvent-elles se faire ?',
'Cancel range' => 'Annulation',
'Until when may bookings be cancelled? Set to 0 to never allow. Set to 0.01 for some seconds (practically always).'
=> 'Jusqu\'à quand peut-on annuler ? Mettre 0 pour jamais. Mettre 0.01 pour quelques secondes avant (presque toujours).',
'Label for free squares' => 'Désignation des ressources libres',
'Custom label for free squares in the calendar; default is Free' => 'Désignation des ressources libres dans le calendrier, par défaut Libre',
'Info (top)' => 'Info (au-dessus)',
'Optional info text, that will be displayed above square details'
=> 'Texte informatif optionnel, qui sera affiché au-dessus du détail de la ressouce',
'Info (bottom)' => 'Info (en-dessous)',
'Optional info text, that will be displayed beneath square details'
=> 'Texte informatif optionnel, qui sera affiché en-dessous du détail de la ressouce',
'Rules' => 'Conditions (CGU)',
'Optional rules that must be accepted prior to booking'
=> 'Les conditions (optionnelles) qui doivent être acceptées avant de réserver',
'Rules (file)' => 'Conditions (fichier)',
'Optional rules as PDF-Document that must be accepted prior to booking'
=> 'Les conditions (optionnelles) qui doivent être acceptées avant de réserver, en document PDF',
'Rules (file name)' => 'Conditions (nom du fichier)',
'Optional file name of the PDF-Document above' => 'Nom optionnel du document PDF ci-dessus',
'Description' => 'Description',
'Optional description of this product' => 'Description de ce produit (optionnel)',
'Options' => 'Options',
'Amount of products to choose from, e.g. 1,2,3 to choose between 1 and 3 articles'
=> 'Combien d\'articles peut-on choisir, ex. 1,2,3 pour 1 à 3 articles',
'New price' => 'Nouveau Prix',
'New time' => 'Nouvelle heure',
'New day' => 'Nouveau jour',
'New period' => 'Nouvelle période',
'Display pricing:' => 'Afficher les prix:',
'For no one' => 'À personne',
'For users' => 'Aux utilisateurs',
'For users and visitors' => 'Aux utilisateurs et visiteurs',
'Optionally set a date from when this product will be available. Determined from the booked date.'
=> 'Fixer une date à partir de laquelle ce produit sera disponible (optionnel). Déterminée à partir de la date de réservation.',
'Optionally set a date until this product will be available. Determined from the booked date.'
=> 'Fixer une date limite après laquelle ce produit ne sera plus disponible (optionnel). Déterminée à partir de la date de réservation.',
'Language' => 'Langage',
'All languages' => 'Tous les Langages',
'Displays this product only to this language' => 'Afficher ce produit uniquement dans ce Langage',
'Edit business terms and privacy policy' => 'Modifier les conditions de vente et la politique de confidentialité',
'Edit billing status names and colors' => 'Modifier les noms et couleurs du statut de facturation',
'Edit Booking-Bill' => 'Modifier les factures de réservation',
'Edit bill' => 'Modifier les factures',
'Business terms (file)' => 'Conditions de vente (fichier)',
'Business terms (file name)' => 'Conditions de vente (nom du fichier)',
'Privacy policy (file)' => 'Politique de confidentialité (fichier)',
'Privacy policy (file name)' => 'Politique de confidentialité (nom du fichier)',
'Optional business terms as PDF-Document that must be accepted prior to registration'
=> 'Les conditions de vente (optionnelles) qui doivent être acceptées avant l\'inscription, en document PDF',
'Optional privacy policy as PDF-Document that must be accepted prior to registration'
=> 'Politique de confidentialité (optionnelles) qui doit être acceptées avant l\'inscription, en document PDF',
'How many people can participate?' => 'Combien de personnes peuvent participer ?',
'There are multiple events for this date and time:' => 'Il y a plusieurs événements pour ce créneau horaire:',
"Pending (pending)\nPaid (paid)\nCancelled (cancelled)\nUncollectable (uncollectable)"
=> "En attente (pending)\nPayé (paid)\nAnnulé (cancelled)\nImpayé (uncollectable)",
'One status option per line and formatted as either: Name Name (internal value) Name (internal value) Color Name Color
For example: Open (pending) #F00 Paid at place #F00
The following values must exist once: pending, paid, cancelled, uncollectable'
=> 'Une valeur par ligne dans les formats suivants: Nom Nom (valeur interne) Nom (valeur interne) Couleur Nom Couleur
Par exemple: Ouvert (pending) #F00 Payé sur place #F00
Les valeurs internes suivantes doivent être uniques: pending, paid, cancelled, uncollectable',
'Invalid billing status selected' => 'Le statut de facturation selectionné est invalide',
'Booking-Bill has been saved' => 'Facture de réservation sauvegardée',
'Booking-Bill position has been created' => 'La facture de réservation a été créée',
'No Booking-Bill position has been created' => 'La facture de réservation n\'a pas été créée',
'Booking-Bill position has been deleted' => 'La facture de réservation a été annulée',
'Time (in minutes)' => 'Temps (en Minutes)',
'Price (in cent)' => 'Prix (en Centimes)',
'New position' => 'Nouvelle position',
'New position by using the pricing rules for this booking' => 'Nouvelle position en utilisant les règles de fixation des prix pour cette réservation',
'Who?' => 'Qui ?',
'Player\'s names' => 'Noms des joueurs',
'Booked by' => 'Réservé par',
'User matched by' => 'Utilisateur déterminé par',
];
================================================
FILE: data/res/i18n/fr-FR/base.php
================================================
'Retour',
'Related pages' => 'En lien',
' by %s' => ' par %s',
' at %s' => ' à %s',
'On %s' => 'On %s',
'On last %s' => 'au dernier %s',
'On next %s' => 'Au prochain %s',
'Tomorrow' => 'Demain',
'Yesterday' => 'Hier',
'%s hours ago' => 'Il y a %s d\'années',
'In %s hours' => 'Il y a %s d\'heures',
'One hour ago' => 'Il y a une heure',
'In one hour' => 'En une heure',
'%s minutes ago' => 'Il y a %s Minutes',
'In %s minutes' => 'En %s Minutes',
'One minute ago' => 'Il y a une minute',
'In one minute' => 'En une minute',
'Now' => 'Maintenant',
'Monday' => 'Lundi',
'Tuesday' => 'Mardi',
'Wednesday' => 'Mercredi',
'Thursday' => 'Jeudi',
'Friday' => 'Vendredi',
'Saturday' => 'Samedi',
'Sunday' => 'dimanche',
'Second' => 'Seconde',
'Seconds' => 'Secondes',
'Minute' => 'Minute',
'Minutes' => 'Minutes',
'Hour' => 'Heures',
'Hours' => 'Heures',
'Day' => 'Jour',
'Days' => 'Jours',
'Calendar' => 'Calendrier',
'from %s to %s' => 'de %s à %s',
'from' => 'de',
'%s to %s' => '%s à %s',
'to' => 'à',
'and' => 'et',
'or' => 'ou',
'for' => 'pour',
'Page not found' => 'Page introuvable !',
'Oops ... something went wrong here' => 'Oops ... ça ne marche pas désolé',
'This page does not (yet) exist' => 'Cette page n\'existe pas (encore)',
'Please %sdrop us a note%s if you were expecting this page.'
=> 'SVP %sLaissez-nous une appréciation%s si vous attendiez cettte page.',
'Back to front page' => 'Retour à l\'accueil',
'Error' => 'Erreur',
'Please %sdrop us a note%s in case of unexpected error messages, %s so that we can repair them quickly.'
=> 'SVP %sLaissez-nous un mot%s si vous voyez un message d\'erreur, %s afin que l\'on répare vite fait.',
'Powered by %s' => 'Propulsé par %s',
'Do your like our service?' => 'Appréciez-vous nos services ?',
'Contact & Feedback' => 'Contact & Retours',
'Our website' => 'Notre site',
'Information about' => 'Infos & images',
'Book by phone' => 'Réserver par téléphone',
'Imprint' => 'Impression',
'You need to activate %sJavaScript%s in you web browser to proceed. If in doubt, switch to another web browser (e.g. Mozilla Firefox).'
=> 'Vous devez activer %sJavaScript%s pour naviguer sur ce site. %s En cas de doute, passez à un autre navigateur (ex: Mozilla Firefox).',
'Square' => 'Court',
'Squares' => 'Courts',
'Player' => 'Joueur',
'Players' => 'Joueurs',
];
================================================
FILE: data/res/i18n/fr-FR/booking.php
================================================
'Réservation',
'%s-Booking' => '%s-Réservation',
'Single' => 'Seul',
'Subscription' => 'Enregistrement',
'Cancelled' => 'Annulation',
'Pending' => 'En cours',
'Paid' => 'Payé',
'Uncollectable' => 'Impayés',
'Public' => 'Public',
'Private' => 'Privé',
'Only once' => 'Une seule fois',
'Daily' => 'Tous les joursTous les jours',
'Every 2 days' => 'Tous les 2 Jours',
'Every 3 days' => 'Tous les 3 Jours',
'Every 4 days' => 'Tous les 4 Jours',
'Every 5 days' => 'Tous les 5 Jours',
'Every 6 days' => 'Tous les 6 Jours',
'Weekly' => 'Hebdomadaire',
'Every 2 weeks' => 'Toutes les 2 semaines',
'Monthly' => 'Mensuel',
'Ambiguous user name "%s" passed (multiple users under this name)'
=> 'Ce nom d\'utilisateur existe dèjà (c\'est ambigu) "%s"',
'This booking does not exist' => 'Cette réservation n\'existe pas',
'This reservation does not exist' => 'Cette réservation n\'existe pas',
'Your %s-booking for %s' => 'Votre %s-Réservation pour le %s',
'we have reserved %s %s, %s for you. Thank you for your booking.'
=> 'Nous avons réservé %s %s, %s pour vous. Merci pour votre réservation.',
'we have just cancelled %s %s, %s for you.'
=> 'Nous venons d\'annuler %s %s, %s pour vous.',
'%s\'s %s-booking for %s' => '%s\'s %s-Réservation pour %s',
'%s\'s %s-booking has been cancelled' => '%s\'s %s-Réservation à été annulée',
];
================================================
FILE: data/res/i18n/fr-FR/calendar.php
================================================
'La date choisie est invalide',
'The passed calendar squares are invalid' => 'Ces courts sont invalides',
'Morning' => 'Matin',
'Afternoon' => 'Après-midi',
'Past' => 'Passé',
'Closed' => 'Fermé',
'Free' => 'Libre',
'Still free' => 'Toujours Libre',
'Conflict' => 'Conflict',
'Occupied' => 'Occupé',
'Your Booking' => 'Votre réservation',
'Loading' => 'Chargement',
'Please wait' => 'Veuillez patienter',
'Arrival' => 'Arrivées',
'Departure' => 'Départs',
'Our %s for the time' => 'Nos %s pour le délai',
'Invalid date choice' => 'Date invalide',
'Persons' => 'Personnes',
];
================================================
FILE: data/res/i18n/fr-FR/frontend.php
================================================
'Aujourd\'hui',
'Date' => 'Date',
'Time' => 'Heure',
'Show' => 'Voir',
'To book %s, %splease register first%s' => 'Pour réserver les %s, %sveuillez vous enregistrer svp%s',
'or simply %s login here' => 'ou simplement %s Connectez-vous ici',
'Email address' => 'Adresse E-Mail',
'Email' => 'E-Mail',
'Phone' => 'Tel.',
'Password' => 'Mot de passe',
'Login' => 'Connexion',
'Logout' => 'Déconnexion',
'New password' => 'Nouveau mot de passe',
'Get additional %shelp and information%s' => 'Obtenir %sune aide ou des Infos supplémentaires%s',
'Online as %s' => 'Connecté en %s',
'Administration' => 'Administration',
'My bookings' => 'Mes Réservations',
'My account' => 'Mon Compte',
];
================================================
FILE: data/res/i18n/fr-FR/service.php
================================================
'Status du System',
'Maintenance' => 'Maintenance',
'Help' => 'Aide',
'We are currently working on this page.' => 'Nous travaillons en ce moment sur cette page.',
'The system is currently not available' => 'Le système est temporairement indisponible',
'System maintenance underway' => 'En travaux',
'We are back as fast as we can. Promised!' => 'Bientôt de retour...',
'The system is available' => 'Le système fonctionne',
];
================================================
FILE: data/res/i18n/fr-FR/setup.php
================================================
'ep-3 Système de réservation',
'ep-3 Bookingsystem Setup' => 'ep-3 ep-3 Système de réservation - Installation',
'imgs/branding/ep3-bs-neg-en.png' => 'imgs/branding/ep3-bs-neg-en.png',
];
================================================
FILE: data/res/i18n/fr-FR/square.php
================================================
'Ce %s est dèjà occupé',
'%sNote:%s Please read and accept the "%s".' => '%sAttention:%s Lire et accepter "%s".',
'%sNote:%s Please read and accept our rules and notes.' => '%sAttention:%s Lire et accepter nos termes et règles.',
'%We are sorry:%s This did not work somehow. Please try again.'
=> '%Désolé:%s cela n\'a pas fonctionné. Veuillez essayer à nouveau.',
'%sCongratulations:%s Your %s has been booked!' => '%sBravo:%s Votre %s est réservé.',
'This booking cannot be cancelled anymore online.' => 'Cette réservation ne pourra plus être annulée en ligne.',
'Your booking has been %scancelled%s.' => 'Votre réservation %sa été annulée%s.',
'Your %s-booking has been cancelled' => 'Vos %s-réservation %sa été annulée%s',
'Disabled' => 'Désactivé',
'Read-Only' => 'Lecture seule',
'Enabled' => 'Activé',
'Unknown' => 'Inconnu',
'This square does not exist' => 'Ce court n\'existe pas',
'This square is currently not available' => 'Ce court n\'est couramment pas disponible',
'The passed start date is invalid' => 'Cette date de début est invalide',
'The passed end date is invalid' => 'Cette date de fin est invalide',
'The passed start time is invalid' => 'Cette heure de début est invalide',
'The passed end time is invalid' => 'Cette heure de fin est invalide',
'The passed time range is invalid' => 'Cette période est invalide',
'The passed time is already over' => 'Cette période est expirée',
'The passed date is still too far away' => 'Cette date est trop futuriste',
'You cannot book more than %s minutes at once' => 'Vous ne pouvez pas réserver plus de %s Minutes en une fois',
'You have no permission to cancel this booking' => 'Vous n\"avez pas la permission d\'annuler cette réservation',
'You have no permission to cancel this subscription' => 'Vous n\"avez pas la permission d\'annuler cette réservation',
'This booking does not contain any distinct reservations' => 'This booking does not contain any distinct reservations',
'This booking does contain multiple distinct reservations (please contact our support)'
=> 'This booking does contain multiple distinct reservations (please contact our support)',
'incl.' => 'incl.',
'including' => 'including.',
'plus' => 'plus.',
'VAT' => 'TVA',
'Summary of your booking:' => 'Résumé de vos réservations:',
'%s items' => '%s Heures',
'Total' => 'Total',
'Update' => 'Actualiser',
'Please note' => 'Notez',
'Rules-document' => 'Règles',
'this will open in a new window' => 'Nous allons ouvrir une nouvelle fenêtre',
'Yes, I have %1$sread and accepted%2$s the "%3$s"' => 'J\'ai lu et accepté%1$s %2$s le "%3$s"',
'Yes, I have %sread and accepted%s these rules and notes' => 'J\'ai lu %set accepté%s ce règlement',
'Your booking will be binding.' => 'Votre réservation sera obligatoire.',
'Your booking will be binding, however, you can cancel it up to %s before it takes place.'
=> 'Votre réservation sera obligatoire. Même si vous pouvez annuler %s avant l\'événement.',
'Complete booking' => 'Valider la Réservation',
'Cancel this booking' => 'Annuler cette réservation',
'Cancel booking' => 'Annuler la réservation',
'Are you sure you want to cancel this booking?' => 'Etes-vous sûr de vouloir annuler cette réservation?',
'Yes, cancel this booking' => 'Oui, j\'annule',
'No, go back' => 'Non, retour',
'This %s is still free.' => 'Ce %s est toujours libre.',
'This %s is still free for %s %s.' => 'Ce %s est toujours libre pour %s %s.',
'%s/%s already occupied' => '%s/%s occupé',
'You are going to book this %s.' => 'Vous allez réserver ce %s.',
'How many %s?' => 'Combien de %s?',
'Consider our additional offers:' => 'Nos offres additionnelles:',
'per item' => 'par service',
'Continue to summary' => 'Vers le sommaire',
'Invalid %s-amount choosen' => 'Comptant choisi %s-Invalide',
'Too many %s for this %s choosen' => 'Trop de %s pour le %s choisit',
'Bookings for this %s are currently not possible online' => 'Ces réservations %s ne sont pas disponibles en ligne',
'None' => 'Aucun',
'Book now' => 'Réservez maintenant',
'Book more' => 'Réservez plus',
'You can %slogin%s or %sregister%s, %s to book this %s' => 'Vous pouvez %svous connectez%s ou %svous enregistrer%s, %s pour réserver ce %s',
'This %s has been %sbooked to you%s.' => 'Ce %s a été %sréservé pous vous%s.',
'This %s is already occupied.' => 'Ce %s est déjà occupé.',
'%s-Check' => '%s-Vérifiez',
'Check if your %s is free for your preferred date.' => 'Voir si votre %s est libre à cette date.',
'Start date' => 'Date début',
'End date' => 'Date fin',
'Check free %s' => 'Voir si dispo %s',
'Check' => 'Voir',
'You need to activate %sJavaScript%s in your web browser to proceed. If in doubt, switch to another web browser (e.g. Mozilla Firefox).'
=> 'vous devez activer %sJavaScript%s dans votre navigateur pour continuer. en cas de doute, passez à un autre navigateur (e.g. Mozilla Firefox).',
'until' => 'jusqu\'à',
'with' => 'avec',
'Change period:' => 'Changer période:',
'Check new period' => 'Nouvelle période',
'The names of the other players are optional' => 'Les noms des autres joueurs est optionnel',
'The names of the other players are required' => 'Les noms des autres joueurs est requis',
'Player\'s name' => 'Nom du joeur',
'and email address' => 'et Adresse: E-Mail',
'and phone number' => ' - tel:',
];
================================================
FILE: data/res/i18n/fr-FR/user.php
================================================
'Désolé vous n\'êtes plus connecté',
'You have no permission for this' => 'Désolé vous n\'avez pas la permission pour cela',
'Forgot password?' => 'Mot de passe oublié ?',
'Forgot your password?' => 'Avez-vous oublié votre de passe ?',
'We have just received your request to reset your password.' => 'Nous venons de recevoir votre demande de réinitialisation de votre mot de passe.',
'Unfortunately, your account is considered a placeholder and thus cannot login.' => 'Malheureusement, votre compte a été défini comme joker et vous ne pouvez pas vous connecter.',
'Unfortunately, your account is currently blocked. Please contact us for support.' => 'Malheureusement, votre compte est bloqué. Veuillez contacter notre support.',
'Unfortunately, your account has not yet been activated. If you did not receive an activation email yet, you can request a new one here:'
=> 'Malheureusement, votre compte n\'a pas encore été activé. Si vous n\'avez pas reçu l\'email d\'activation, vous pouvez vous en renvoyer un ici:',
'Simply visit the following website to type your new password:' => 'Visitez simplement ce site et tapez votre mot de passe:',
'However, you are using a privileged account. For safety, you cannot reset your password this way. Please contact the system support.'
=> 'Bien que vous utilisiez un compte privilégié. Par sécurité, nous ne pouvons réinitialiser votre mot de passe de cette façon, Veuillez contacter notre support.',
'Unfortunately, your account seems somewhat unique, thus we are unsure how to treat it. Mind contacting us?'
=> 'Malheureusement, votre compte semble quelque peu unique, nous ne savons pas vraiment comment le traiter. Veuillez-nous contacter?',
'All right, you should receive an email from us soon' => 'Très bien, vous devriez recevoir un email de nous bientôt',
'if we find a valid user account with this email address' => 'si nous trouvons un compte utilisateur valide avec cette adresse e-mail',
'Your token to reset your password is invalid or expired. Please request a new email.'
=> 'Votre jeton pour réinitialiser votre mot de passe est invalide ou expiré. Veuillez demander un nouveau courriel SVP.',
'All right, your password has been changed. You can now log into your account.'
=> 'Très bien, votre mot de passe a été changé. Vous pouvez maintenant vous connecter à votre compte.',
'New registration waiting for activation' => 'Nouvel inscription en attente d\'activation',
'A new user has registered to your %s. According to your configuration, this user will not be able to book %s until you manually activate him.'
=> 'Un nouvel utilisateur c\'est inscrit à %s. D\'après votre configuration il ne sera pas en mesure de réserver des %s jusqu\'à ce que vous l\'activiez manuellement.',
'Your registration to the %s %s' => 'Votre inscription à %s %s',
"welcome to the %s %s!\r\n\r\nThank you for your registration to our service.\r\n\r\nBefore you can completely use your new user account to book spare %s online, you have to activate it by simply clicking the following link. That's all!\r\n\r\n%s"
=> "Bienvenue à %s %s!\r\n\r\nMerci pour votre inscription à notre service.\r\n\r\nAvant de pouvoir pleinement utiliser votre compte et réserver des %s en ligne, vous devez l\'activer en allant sur le lien suivant. C\'est tout!\r\n\r\n%s",
'Your activation code seems invalid. Please try again.' => 'Votre code d\'activation semble invalide. Veuillez réessayer SVP.',
'You cannot manually activate your account currently' => 'Vous ne pouvez pas activer manuellement votre compte actuellement',
'We have just received your request for a new user account activation email.' => 'Nous venons de recevoir votre demande pour un nouvel email d\'activation de compte utilisateur.',
'Unfortunately, your account is considered a placeholder and thus cannot be activated.' => 'Malheureusement, votre compte a été défini comme joker et ne peut pas être activé.',
"Before you can completely use your new user account to book spare %s online, you have to activate it by simply clicking the following link. That's all!\r\n\r\n%s"
=> "BAvant de pouvoir pleinement utiliser votre compte et réserver des %s en ligne, vous devez l\'activer en allant sur le lien suivant. C\'est tout!\r\n\r\n%s",
'However, your account has already been activated. You can login whenever you like!'
=> 'Cependant, votre compte a déjà été activé. Vous pouvez vous connecter quand vous voulez.',
'Your %sphone number%s has been updated' => 'Votre %snuméro de téléphone%s a été mis à jour',
'New email address at %s %s' => 'Nouvelle adresse email à %s %s',
"You have just changed your account's email address to this one.\r\n\r\nBefore you can completely use your new email address to book spare %s online again, you have to activate it by simply clicking the following link. That's all!\r\n\r\n%s"
=> "Vous venez de changer l'adresse email de votre compte pour celle-ci. Avant de pouvoir pleinement utiliser votre compte et réserver des %s en ligne, vous devez l\'activer en allant sur le lien suivant. C\'est tout!\r\n\r\n%s",
'Your %semail address%s has been updated' => 'Votre %sadresse email%s a été mise à jour',
'Your %snotification settings%s have been updated' => 'Vos %paramètres de notifications%s ont été mis à jour',
'Your %spassword%s has been updated' => 'Votre %smot de passe%s a été mise à jour',
'This is not your correct password' => 'Ce n\'est pas le mot de passe correct',
'Your %suser account has been deleted%s. Good bye!' => 'Votre %scompte utilisateur a été effacé%s. Au revoir!',
'Due to too many login attempts, temporarily blocked until %s' => 'En raison d\'un grand nombre de tentatives de connexion, ce compte est bloqué temporairement jusqu\'à %s',
'This account is considered a placeholder and thus cannot login' => 'Malheureusement, ce compte a été défini comme joker et ne peut pas se connecter.',
'Email address and/or password invalid' => 'Adresse email et/ou mot de passe invalide(s)',
'This account is currently blocked' => 'Ce compte est temporairement bloqué',
'This account has not yet been activated' => 'Ce compte n\'a pas encore été activé',
'Welcome, %s' => 'Bienvenue, %s',
'User' => 'Utilisateur',
'Placeholder' => 'Joker',
'Deleted user' => 'Utilisateur supprimé',
'Blocked user' => 'Utilisateur bloqué',
'Waiting for activation' => 'En atttente d\'activation',
'Enabled user' => 'Utilisateur accepté',
'Assist' => 'Employé',
'Admin' => 'Administrateur',
'Mr.' => 'Mr.',
'Mrs' => 'Mme.',
'Family' => 'Famille',
'Firm' => 'Société',
'May manage users' => 'Peut gérer les utilisateurs',
'May manage bookings' => 'Peut gérer les réservations',
'May manage events' => 'Peut gérer les événements',
'May change configuration' => 'Peut changer la configuration',
'Can see the admin menu' => 'Peut voir le menu admin',
'Can see the past in calendar' => 'Peut voir le passé dans calendrier',
'Can see names and data in calendar' => 'Peut voir les nom et données dans le calendrier',
'May create single bookings' => 'Peut créer des réservations simple',
'May cancel single bookings' => 'Peut annuler des réservations simple',
'May delete single bookings' => 'Peut supprimer des réservations simple',
'May create multiple bookings' => 'Peut créer des réservations multiples',
'May cancel multiple bookings' => 'Peut annuler des réservations multiples',
'May delete multiple bookings' => 'Peut supprimer des réservations multiples',
'Request activation mail' => 'Demander un email d\'activation',
'Resend activation email' => 'Renvoyer un email d\'activation',
'Were you not happy with our service? Please tell us why you leave. Thank you!'
=> 'Vous n\'étiez pas satisfait de nos services? Veuillez s\'il vous plait, nous dire pourquoi vous partez. Merci beaucoup!',
'Delete account' => 'Supprimer ce compte',
'Your current password' => 'Votre mot de passe actuel',
'Your new password' => 'Votre nouveau mot de passe',
'Please provide your email address' => 'Veuillez renseigner votre adresse email',
'Please type your email address here' => 'Veuillez renseigner votre adresse email ici',
'Please type your correct email address here' => 'Veuillez renseigner une adresse email correcte ici',
'We could not verify your email provider' => 'Nous n\'avons pas été en mesure de vérifier votre adresse email',
'Trash mail addresses are currently blocked - sorry' => 'Les adresses email "poubelles" sont actuellement bloqués',
'This email address has already been registered' => 'Cette adresse email a déjà été inscrite',
'Both email addresses must be identical' => 'Les deux adresses email doivent être identiques',
'Both passwords must be identical' => 'Die beiden Passwörter sind verschieden',
'Please type your password here' => 'Les deux mot de passe doivent être identiques',
'Please type a new password here' => 'Veuillez saisir un nouveau mot de passe ici',
'Please type your email address again to prevent typing errors' => 'Veuillez re-saisir votre adresse email ici afin d\'éviter toute erreur de frappe',
'Please type your password again to prevent typing errors' => 'Veuillez re-saisir votre mot de passe ici afin d\'éviter toute erreur de frappe',
'Please type your new password again to prevent typing errors' => 'Veuillez re-saisir votre nouveau mot de passe ici afin d\'éviter toute erreur de frappe',
'Your new password should be at least %min% characters long' => 'Votre nouveau mot de passe doit au moins comporter %min% caractères',
'Notify on bookings and cancellations' => 'Notifications pour les réservations et annulations',
'We can send you confirmations per email' => 'Nous pouvons vous envoyer des confirmations par email',
'Update phone number' => 'Mettre à jour le numéro de téléphone',
'Update email address' => 'Mettre à jour l\'adresse email',
'Update settings' => 'Mettre à jour la configuration',
'Update password' => 'Mettre à jour le mot de passe',
'Change password' => 'Changer le mot de passe',
'Please type your phone number here' => 'Veuillez saisir votre numéro de téléphone ici',
'This phone number is somewhat short ...' => 'Ce numéro de téléphone semble un peu court',
'This phone number contains invalid characters - sorry' => 'Désolé mais ce numéro de téléphone contient des caractères invalides',
'Your password will be safely encrypted' => 'Votre mot de passe sera encrypté par sécuritét',
'Please type your password again' => 'Veuillez saisir votre mot de passe à nouveau',
'We only use this to inform you about changes to your bookings' => 'Nous ne faisons ça que pour vous informer à propos de vos réservations',
'Salutation' => 'Salutation',
'First & Last name' => 'Prénom & Nom',
'Last name' => 'Nom',
'Street & Number' => 'Rue et numéro',
'Street number' => 'Adresse',
'Postal code & City' => 'Code postal & Ville',
'City' => 'Ville',
'Phone number' => 'Téléphone',
'Birthday' => 'Date de naissance',
'This is optional' => 'C\'est optionnel',
'Complete registration' => 'Compléter votre inscription',
'Please type your name here' => 'Veuillez saisir votre nom ici',
'Your name is somewhat short ...' => 'Votre nom semble trop court ...',
'Your name contains invalid characters - sorry' => 'Désolé mais, votre nom contient des caractères invalides',
'Your last name is somewhat short ...' => 'Votre prénom semble trop court ...',
'Your last name contains invalid characters - sorry' => 'Votre prénom contient des caractères invalides',
'Please type your street name here' => 'Veuillez renseigner votre rue ici',
'This street name is somewhat short ...' => 'Le nom de cette rue semble trop court ...',
'This street name contains invalid characters - sorry' => 'Désolé mais, le nom de cette rue contient des caractères invalides',
'Please type your street number here' => 'Veuillez saisir votre numéro de rue ici',
'This street number contains invalid characters - sorry' => 'Désolé mais, votre numéro de rue contient des caractères invalides',
'Please type your postal code here' => 'Veuillez saisir votre code postal ici',
'Please provide a correct postal code' => 'Veuillez saisir un code postal correcte',
'Please type your city here' => 'Veuillez saisir votre ville ici',
'This city name is somewhat short ...' => 'Le nom de cette ville semble court ...',
'This city name contains invalid characters - sorry' => 'Désolé mais, le nom de cette ville contient des caractères invalides',
'Please leave this field empty' => 'Veuillez laisser ce champs vide',
'Please register about our website only' => 'S\'il vous plaît utiliser uniquement notre formulaire d\'inscription',
'You were too quick for our system! Please wait some seconds and try again. Thank you!' => 'Vous aves été trop rapide pour le système! Veuillez attendre quelques seconde avant de ré-essayer.',
'User name too short' => 'Nom d\'utilisateur trop court',
'This user does not exist' => 'Cette utilisateur n\'existe pas',
'You have no imminent bookings.' => 'Vous n\'avez pas de réservation imminente.',
'You have not booked any %s yet.' => 'Vous n\'avez réservé aucun %s pour l\'instant.',
'You have already booked one %s.' => 'Vous avez déjà réservé un %s.',
'You have already booked %s %s.' => 'Vous avez déjà réservé %s %s.',
'If you did not receive an activation email from us after registration, you can request a new one here.'
=> 'Si vous n\'avez pas reçu d\'email d\'activation après votre inscription, vous pouvez en demander un ici.',
'Therefore, please type the email adress you used for registration.' => 'Dans ce cas, veuillez saisir l\'adresse email utilisée lors de votre inscription.',
'Your user account has been activated. You can now login with your email address and password. Have fun!'
=> 'Votre compte a été activé. Vous pouvez maintenant vous connecter avec vos email et mot de passe. Have fun!',
'Now you can type a new password for your user account.' => 'Vous pouvez saisir un nouveau mot de passe pour votre compte maintenant.',
'No need to be sad. You may simply type your email address here and you will soon be able to choose a new password.'
=> 'Pas d\'inquiétude. Vous pouvez saisir votre adresse email ici et serez bientôt en mesure de choisir un mot de passe.',
'Registration complete' => 'Inscription complète',
'The registration is complete and your user account has been created successfully'
=> 'L\'Inscription est complète et votre compte a été créé avec succès',
'You can now login with your email address and password. Have fun!'
=> 'Vous pouvez maintenant vous connecter avec vos email et mot de passe. Have fun!',
'However, your user account is %snot yet activated%s.'
=> 'Cependant, votre compte n\'est %spas encore activé%s.',
'This will happen during a quick manual verification of your user account data.'
=> 'Cela consistera en une rapide vérification des informations saisies.',
'Please be patient, this will be done soon.'
=> 'Veuillez être patient, ce sera bientôt fini.',
'The only step remaining is to %sactivate your user account%s.'
=> 'La seule étape restante est d\'%sactiver votre compte%s.',
'For this, we just sent you an email with an activation link within. Please check.'
=> 'Nous venons de vous envoyer un email d\'activation contenant un lien à cet effet. Veuillez vérifier.',
'If you did not receive an email from us, you can always %srequest a new one%s.'
=> 'Si vous n\'avez reçu aucun email de notre part, vous pouvez toujours %demander un renvoi%s.',
'Register now' => 'Inscrivez-vous',
'Registration' => 'Inscription',
'Activation' => 'Activation',
'Welcome to our %s' => 'Bienvenue à notre %s',
'You probably guessed it: To use our service, that is to book spare %s online, you need to create your own user account first.'
=> 'Vous l\'avez probablement deviné: Pour utiliser notre service, la réservation de %s en ligne, vous devez d\'abord créer un compte utilisateur.',
'The registration is of course free of cost and nonbinding.' => 'L\'inscription est bien sûr sans frais et sans engagement.',
'We are very sorry, but the registration is currently not possible.' => 'Désolé mais, L\'inscription n\'est pas possible en ce moment.',
'Login data' => 'Données de connexion',
'Account data' => 'Données du compte',
'Personal data' => 'Données Personnelles',
'please inform us about changes, so we can update this data' => 'Veuillez nous informer de tout changement, afin que nous tenions le système à jours',
'Note: You need to activate your account again if you update your email address.'
=> 'NB: Vous devrez activer votre compte encore une fois si vous changez votre email.',
'Update notifications' => 'Notifications',
'Delete this account' => 'Supprimer ce compte',
'Bye, %s' => 'Au revoir, %s',
'If you have already registered, you can login here with your email address and start booking %s.'
=> 'Si vous êtes déjà inscrit, vous pouvez vous connecter ici avec votre adresse email et commencer à réserver des %s .',
'Bill' => 'Facture',
'Booking-Bill' => 'Facture de réservation',
'I agree to %s' => 'J\'accèpte %s',
'Please agree to this' => 'Veuillez accepter ça',
/* Email */
'Dear' => 'Cher Monsieur / Madame',
'Hello' => 'Bonjour',
'This was an automated message from the system.' => 'Ceci est un message automatique.',
'Originally sent to %s (%s).' => 'Envoyé à l\'origine à %s (%s).',
'Sincerely' => 'Meilleures',
'Your' => 'salutations',
];
================================================
FILE: data/res/i18n/hu-HU/backend.php
================================================
'Felhasználók',
'Create, edit or delete the users of your system' => 'A rendszerben a felhasználók létrehozása, szerkesztése vagy törlése',
'Bookings' => 'Foglalások',
'Create, edit or delete the bookings of your system' => 'A rendszerben a foglalások létrehozása, szerkesztése vagy törlése',
'Event' => 'Esemény',
'Events' => 'Események',
'Create, edit or delete the events of your system' => 'A rendszerben az események létrehozása, szerkesztése vagy törlése',
'Statistic' => 'Statisztikák',
'User-Statistic' => 'Felhasználó-statisztikák',
'Booking-Statistic' => 'Foglalás-statisztikák',
'Event-Statistic' => 'Esemény-statisztikák',
'Configuration' => 'Beállítás',
'Configuration has been saved' => 'Beállítás elmentve',
'Configuration has been updated' => 'Beállítás frissítve',
'Configuration is (partially) invalid' => 'Beállítás (részlegesen) érvénytelen',
'Configure your system just as you need it' => 'Allítsa be a rendszert ahogyan szeretné',
'Here you can configure and fine tune your system just as you need it.'
=> 'Itt be tudja állítani és finomhangolni a rendszert ahogyan szeretné.',
'User-Administration' => 'Felhasználó-adminisztráció',
'Here you can create, edit or delete the users of your system.' => 'Itt létre tud hozni, szerkeszteni, vagy törölni a felhasználókat.',
'Booking-Administration' => 'Foglalás-adminisztráció',
'Here you can create, edit or delete the bookings of your system.' => 'Itt létre tud hozni, szerkeszteni, vagy törölni a foglalásokat.',
'Event-Administration' => 'Esemény-adminisztráció',
'Here you can create, edit or delete the events of your system.' => 'Itt létre tud hozni, szerkeszteni, vagy törölni az eseményeket.',
'Name or number' => 'Név vagy szám',
'Search' => 'Keresés',
'Advanced search' => 'Haladó keresés',
'%sNo users found%s for this search' => '%sNem találhatók felhasználók%s ehhez a kereséshez',
'%sNo bookings found%s for this search' => '%sNem találhatók foglalások%s ehhez a kereséshez',
'%sNo events found%s for this search' => '%sNem találhatók események%s ehhez a kereséshez',
'New user' => 'Új felhasználó',
'New booking' => 'Új foglalás',
'New event' => 'Új esemény',
'User has been saved' => 'Felhasználó elmentve',
'User has been deleted' => 'Felhasználó törölve',
'Booking has been saved' => 'Foglalás elmentve',
'Booking has been deleted' => 'Foglalás törölve',
'Booking has been cancelled' => 'Foglalás lemondva',
'Reservation has been deleted' => 'Foglalás törölve',
'Event has been saved' => 'Esemény elmentve',
'Event has been deleted' => 'Esemény törölve',
'Square has been saved' => 'Pálya elmentve',
'Square has been deleted' => 'Pálya törölve',
'User status has been set to deleted' => 'Felhasználó státus törlésre állítva',
'Edit' => 'Szerkesztés',
'Save' => 'Mentés',
'Save and back' => 'Mentés és vissza',
'Delete' => 'Törlés',
'Edit user' => 'Felhasználó szerkesztése',
'No.' => 'Szám',
'Notes' => 'Jegyzet',
'Arbitrary name or identifier for this user' => 'Választott név vagy felhasználó azonosító',
'Privileges' => 'Jogok',
'Press CTRL to select multiple items' => 'Nyomjon ctrl billentyűt több elem kiválasztásához',
'Please type a name here' => 'Kérem adjon meg egy nevet',
'Please type a number here' => 'Kérem adjon meg egy számot',
'Please type something here' => 'Kérem írjon be valamit',
'Please type more characters here' => 'Kérem adjon meg több karaktert',
'Please provide the time in format HH:MM' => 'Kérem adja meg az idő formátumot OO:PP',
'Active' => 'Aktív',
'Last activity' => 'Legutóbbi aktivitás',
'Last IP' => 'Legutóbbi IP',
'Created' => 'Létrehozva',
'Created by' => 'Létrehozva a következő által',
'Are you sure you want to delete this user?' => 'Biztos benne hogy törli ezt a felhasználót?',
'Yes, delete this user' => 'Igen, törölje ezt a felhasználót',
'Delete user' => 'Felhasználó törlése',
'Since this user has already bookings, he will be set to deleted but kept in the database'
=> 'Mivel ennek a felhasználónak már vannak foglalásai ezért törölt státuszra lesz állítva de megmarad az adatbázisban',
'Delete this booking' => 'Foglalás törlése',
'Are you sure you want to delete this booking?' => 'Biztos benne hogy törli ezt a foglalást?',
'Yes, delete this booking' => 'Igen, törölje ezt a foglalást',
'Are you sure you want to delete this reservation?' => 'Biztos benne hogy törli ezt a foglalást?',
'Yes, delete this reservation' => 'Igen, törölje ezt a foglalást',
'Are you sure you want to delete this square?' => 'Biztos benne hogy törli ezt a pályát?',
'Yes, delete this square' => 'Igen, törölje ezt a pályát',
'Since this square has already bookings, it will be set to disabled but kept in the database'
=> 'Mivel ehhez a pályához már volt foglalás, ezért törölt státuszra lesz állítva de megmarad az adatbázisban',
'Are you sure you want to delete this product?' => 'Biztos benne hogy törli ezt a terméket?',
'Yes, delete this product' => 'Igen, törölje ezt a terméket',
'If this booking is cancelled, it will disappear from the calendar, but remain in the database.'
=> 'Ha ezt a foglalást lemondja, el fog tünni a naptárból, de megmarad az adatbázisban.',
'The booking itself will not be changed. Only the reservation at this date will be deleted.'
=> 'A foglalás maga nem fog megváltozni. Csak a dátumhoz tartozó igénylés kerül törlésre.',
'This booking consists of multiple reservations:' => 'Ez a foglalás több igénylésből tevődik össze:',
'What do you want to edit?' => 'Melyiket akarja szerkeszteni?',
'Only this one reservation' => 'Csak ezt az egy igénylést',
'The entire booking' => 'A teljes foglalást',
'Delete this event' => 'Törölje ezt az eseményt',
'Are you sure you want to delete this event?' => 'Biztos benne hogy törli ezt az eseményt?',
'Yes, delete this event' => 'Igen, törölje ezt az eseményt',
'You can use filters like these to narrow your search:' => 'Használhat szűrést, amivel szűkítheti a keresést:',
'You can also combine a search term and multiple filters like this:'
=> 'Kombinálhatja is a kereső kifejezéseket és szűrőke, hasonlóan mint ez:',
'User ID' => 'Felhasználó ID',
'Square ID' => 'Pálya ID',
'[custom]' => '[egyedi]',
'Users total' => 'Felhasználók összesen',
'Placeholders total' => 'Helykitöltő összesen',
'Names and text' => 'Nevek és szövegek',
'Names and text have been saved' => 'Nevek és szövegek elmentve',
'What is the name of your service? What is your name?' => 'Mi a szolgáltatása elnevezése? Mi az ön neve?',
'Info page' => 'Információs oldal',
'Info page has been saved' => 'Információs oldal elmentve',
'Info page text is too short' => 'Az információs oldal szöveg túl rövid',
'Which text should appear on the info page (%s)?' => 'Melyik szöveg jelenjen meg az információs oldalon (%s)?',
'Help page' => 'Segítség oldal',
'Help page has been saved' => 'Segítség oldal elmentve',
'Help page text is too short' => 'A segítség oldalon a szöveg túl rövid',
'Which text should appear on the help page?' => 'Melyik szöveg jelenjen meg a segítség oldalon?',
'Which %s do you have? What are their names?' => 'Melyik %s vannak? Mik a neveik?',
'Pricing' => 'Árak',
'Pricing rules' => 'Ár szabályok',
'Pricing rules have been saved' => 'Ár szabályok elmentve',
'Unknown pricing rules error' => 'Ismeretlen ár szabály hiba',
'How much do bookings cost for your %s?' => 'Mennyibe kerülnek a foglalások a %s?',
'Products' => 'Termékek',
'Which additional products or services do you offer with your bookings?'
=> 'Milyen további termékeket vagy szolgáltatásokat ajánl fel a foglalásokhoz?',
'Behaviour' => 'Működés',
'How does registration work? How many days are displayed in the calendar?'
=> 'Hogyan működik a regisztráció? Mennyi nap látszik a naptárban?',
'To provide language dependent content here, simply switch the global system language.'
=> 'Nyelvfüggő tartalom megadásához egyszerűen változtassa meg a globális rendszer nyelvet.',
'New %s' => 'Új %s',
'New product' => 'Új termék',
'Price' => 'Ár',
'Price per item' => 'Egységár',
'All %s' => 'Összes %s',
'All squares' => 'Összes pálya',
'All' => 'Összes',
'Edit square info and rule texts' => 'Pálya információ és szabályok szerkesztése',
'Current file:' => 'Aktuális file:',
'The name should be at least %min% characters long' => 'A név legalább %min% karakter hosszú kell hogy legyen',
'The name must not be numeric' => 'A név nem lehet csak számból álló',
'This %s has multiple reservations here:' => 'Ez %s több igénylést tartalmaz:',
'Booking created' => 'Foglalás létrehozva',
'Booking created: %s' => 'Foglalás létrehozva: %s',
'Booking created: %s by %s' => 'Foglalás létrehozva: %s a következő által %s',
'Booking cancelled: %s by %s' => 'Foglalás lemondva: %s a következő által %s',
'Admin users can only be edited by admins' => 'Admin felhasználók csak másik admin felhasználó által szerkeszthetőek',
'Admin status can only be given by admins' => 'Admin státusz csak adminok által adhatóak',
'Privileges can only be edited by admins' => 'Jogosultságokat csak adminok szerkeszthetik',
'These are only visible for administration' => 'Ezek csak adminisztrátorok által láthatóak',
'Billing status' => 'Számlázási státusz',
'Billing total' => 'Számlázandó összesen',
'Billing status options' => 'Számlázás státusz beállítások',
'Number of players' => 'Játékosok száma',
'Booked to' => 'Lefoglalva ',
'Edit user once saved' => 'Felhasználo szerkesztése mentés után',
'Edit booking bills once saved' => 'Foglalási számlák szerkesztése mentés után',
'Date (Start)' => 'Dátum (kezdete)',
'Date (End)' => 'Dátum (vége)',
'Time (Start)' => 'Idő (kezdete)',
'Time (End)' => 'Idő (vége)',
'Clock' => 'Óra',
'Repeat' => 'Ismétlés',
'Edit time or date range' => 'Idő és dátum tartomány szerkesztése',
'Time and date range can only be edited on subscription bookings' => 'Idő és dátum tartomány csak az előfizetéses foglalásoknál lehetséges',
'Change the time range of all unmodified reservations of this booking:' => 'Idő módosíása az összes nem módosított foglalásnál:',
'Change the date range and/or interval of this booking:' => 'Dátum módosítása ennél a foglalásnál:',
'Invalid date' => 'Érvénytelen dátum',
'Essentially disables the system for the public, but allows administrators to still login'
=> 'Letiltja a rendszert a nyilvánosság elöl. de az adminisztrátorok még be tudnak jelentkezni',
'Message' => 'Üzenet',
'This message optionally appears in maintenance mode' => 'Ez az üzenet opcionálisan megjelenik karbantartás módban',
'This message optionally appears when registration is disabled' => 'Ez az üzenet opcionálisan megjelenik amikor a regisztráció le van tiltva',
'Sets if new users are allowed to register' => 'Szabályozza, hogy a regisztráció engedélyezett-e',
'Immediately' => 'Azonnal',
'Manually (per backend)' => 'Manuálisan (backend-ben)',
'Automatically (per email)' => 'Automatikusan (email-ben)',
'Sets how new users are activated after registration' => 'Szabályozza, hogy az új felhasználók hogyan aktiválódhatnak regisztráció után',
'Days in calendar' => 'Napok a naptárban',
'Sets how many days are displayed in the calendar' => 'Szabályozza, hogy hány nap látszódik a naptárban',
'Hide these days' => 'Az alábbi napok elrejtése',
'Day names (like Sunday) or concrete dates (like 2016-08-16]; Separated by line breaks or commas; Force concrete dates to be shown by adding a plus (like +2016-08-30)'
=> 'Nap nevek (pl. Vasárnap) vagy konkrét dátum (pl. 2016-08-16]; Új sorral vagy pontosvesszővel elválasztva; Konkrét dátum megjelenítésének a kikényszerítéséhez plusz jelet kell megadni (pl. +2016-08-30)',
'Your name' => 'Az ön neve',
'Will be shown as the operator of this site. Displayed next to the logo, for example.'
=> 'Ez mutatja az oldal üzemeltetőjét. Megjelenítve a logó mellett, például.',
'Your abbreviation' => 'Az ön rövidítése',
'Short form or abbreviation of your name. Displayed in emails, for example.'
=> 'A nevének a rövidítése. Email-ben megjelenítve, például.',
'Your email address' => 'Az ön Email címe',
'Will be used for system notifications. Might also be displayed to users for help.'
=> 'A rendszerüzenetek kézbesítéséhez használjuk. Megjeleníthető a felhasználók segítése céljából is.',
'Send user emails like booking/cancel confirmation to this address as well'
=> 'Küldjön a felhasználó emailekről (mint például foglalás/lemondás megerősités) másolatot erre a címre is',
'Your phone number' => 'Az ön telefonszáma',
'Displayed for booking by phone.'
=> 'Megjelenítve telefonos foglaláshoz.',
'Your website' => 'Az ön weboldala',
'The address of your website. Displayed in the header, for example.'
=> 'Az ön weboldalának a címe. Például a fejlécben megjelenítve.',
'Your contact page' => 'Az ön kapcsolati oldala',
'The address of your website\'s contact page. Displayed in the header, for example.'
=> 'A weboldalának a kapcsolati címe. Például a fejlécben megjelenítve.',
'Your imprint page' => 'Az ön impresszum oldala',
'Your privacy policy page' => 'Az ön adatvédelmi nyilatkozat oldal',
'The address of your website\'s imprint page.' => 'Az ön impresszum oldalának a címe.',
'The address of your website\'s privacy policy page.' => 'Az ön adatvédelmi irányelv oldalának a címe.',
'Name of the system' => 'A rendszer neve',
'The system presents itself under this name. Displayed next to the logo, for example.'
=> 'A rendszer önmagát ezen a néven mutatja be. Például ez látható a logó mellett.',
'System abbreviation' => 'Rendszerbeli rövidítések',
'Short form or abbreviation of the system name. Displayed in emails, for example.'
=> 'A rendszer rövid neve vagy rövidítése. Például az emailben jelenik meg.',
'Description of your service' => 'A szolgáltatásának a leírása',
'One or two short sentences recommended.' => 'Egy két rövid mondat javasolt.',
'Notation of your "squares"' => 'Mit használjunk a "pályák" elnevezés helyett',
'Notation of your "players"' => 'Mit használjunk a "játékosok" elnevezés helyett',
'Name of your facility' => 'A létesítményének az elnevezése',
'Displayed in the header, for example. Must start with a lower cased noun marker.'
=> 'Például a fejlécben megjelenítve. Kisbetűs főnévvel kell kezdődnie.',
'Optional message when readonly' => 'Opcionális üzenet csak olvasható módban',
'Priority' => 'Prioritás',
'Capacity' => 'Kapacitás',
'How many players fit into one square?' => 'Hány játékos fér el egy pályán?',
'Don\'t ask for other player\'s names' => 'Ne kérjen további játékos neveket',
'Ask for other player\'s names (optional)' => 'Opcionálisan megadhatóak további játékos nevek',
'Ask for other player\'s names and email address (optional)' => 'Opcionálisan megadhatóak további játékos nevek és email címek',
'Ask for other player\'s names and phone number (optional)' => 'Opcionálisan megadhatóak további játékos nevek és telefonszámok',
'Ask for other player\'s names, email address and phone number (optional)' => 'Opcionálisan megadhatóak további játékos nevek, email címek és telefonszámok',
'Ask for other player\'s names (required)' => 'Kötelezően megadandóak további játékos nevek',
'Ask for other player\'s names and email address (required)' => 'Kötelezően megadandóak további játékos nevek és email címek',
'Ask for other player\'s names and phone number (required)' => 'Kötelezően megadandóak további játékos nevek és telefonszámok',
'Ask for other player\'s names, email address and phone number (required)' => 'Kötelezően megadandóak további játékos nevek, email címek és telefonszámok',
'Multiple bookings' => 'Többszörös foglalás',
'May this square be booked multiple times until its full?'
=> 'Ez a pálya foglalható többszörösen, amíg tele nem lesz (pálya kapacitása)?',
'Visibility of names' => 'Nevek láthatósága',
'For other users that are logged in' => 'Bejelentkezett felhasználók számára',
'Publicly for everyone' => 'Minden látogató számára',
'Who should see the names of the booking users in the calendar?'
=> 'Kik láthatják a foglalások tulajdonosait a naptárban?',
'Time block' => 'Foglalható időblokk',
'Time block (min. bookable)' => 'Minimális foglalható időblokk',
'Allow min. bookable time block for admins only' => 'Minimum foglalási időblokk csak az adminok számára',
'Users still can only book the normal time blocks then' => 'Ekkor a felhasználók csak normál időblokkokat tudnak foglalni',
'Time block (max. bookable)' => 'Maximális foglalható időblokk',
'Booking range' => 'Foglalhatósági időtartomány',
'How many days in advance can squares be booked?' => 'Hány nappal korábban lehet lefoglalni a pályákat?',
'Cancel range' => 'Lemondási időtartomány',
'Until when may bookings be cancelled? Set to 0 to never allow. Set to 0.01 for some seconds (practically always).'
=> 'Mennyi idővel korábban lehetséges lemondani egy foglalást? 0-ra állítva nem lehet lemondani. 0.01-re állítva pár másodperc, azaz praktikusan bármikor lemondható.',
'Label for free squares' => 'A szabad pálya címkéje',
'Custom label for free squares in the calendar; default is Free' => 'Egyedi címke a szabad pályák jelzésére a naptárban; az alapértelmezett a Szabad',
'Info (top)' => 'Info (fent)',
'Optional info text, that will be displayed above square details'
=> 'Opcionális info szöveg, ami a pálya részletei fölött jelenik meg',
'Info (bottom)' => 'Info (alul)',
'Optional info text, that will be displayed beneath square details'
=> 'Opcionális info szöveg, ami a pálya részletei alatt jelenik meg',
'Rules' => 'Szabályok',
'Optional rules that must be accepted prior to booking'
=> 'Opcionális szabályok, melyeket el kell fogadni mielőtt pálya foglalást indíthatnak',
'Rules (file)' => 'Szabályok (fájl)',
'Optional rules as PDF-Document that must be accepted prior to booking'
=> 'Opcionális szabályok PDF dokumentumban, melyet el kell fogadni mielőtt pálya foglalást indíthatnak',
'Rules (file name)' => 'Szabályok (fájlnév)',
'Optional file name of the PDF-Document above' => 'Opcionális PDF dokumentum fájlnév',
'Description' => 'Leírás',
'Optional description of this product' => 'Opcionális leírás ehhez a termékhez',
'Options' => 'Opciók',
'Amount of products to choose from, e.g. 1,2,3 to choose between 1 and 3 items'
=> 'Termékek száma, amiből választani lehet, pl. 1,2,3 hogy 1 és 3 között lehessen választani',
'New price' => 'Új ár',
'New time' => 'Új idő',
'New day' => 'Új nap',
'New period' => 'Új periódus',
'Display pricing:' => 'Árak megjelenítése:',
'For no one' => 'Senkinek',
'For users' => 'Regisztrált felhasználóknak',
'For users and visitors' => 'Regisztrált felhasználóknak és látogatóknak',
'Optionally set a date from when this product will be available. Determined from the booked date.'
=> 'Opcionálisan beállítható kezdő dátum amikortól a termék elérhető. A foglalás dátuma határozza meg, hogy választható lesz-e.',
'Optionally set a date until this product will be available. Determined from the booked date.'
=> 'Opcionálisan beállítható vég dátum amikortól a termék már nem érhető el. A foglalás dátuma határozza meg, hogy választható-e.',
'Language' => 'Nyelv',
'All languages' => 'Összes nyelv',
'Displays this product only to this language' => 'Termék megjelenítése csak ezen a nyelven',
'Edit business terms and privacy policy' => 'Üzleti szabályok és adatvédelem szerkesztése',
'Edit billing status names and colors' => 'Számlázási státuszok és színeik szerkesztése',
'Edit Booking-Bill' => 'Foglalási számlák szerkesztése',
'Edit bill' => 'Számla szerkesztése',
'Business terms (file)' => 'Általános keretszerződés (file)',
'Business terms (file name)' => 'Általános keretszerződes (file név)',
'Privacy policy (file)' => 'Adatvédelmi nyilatkozat (file)',
'Privacy policy (file name)' => 'Adatvédelmi nyilatkozat (file név)',
'Optional business terms as PDF-Document that must be accepted prior to registration'
=> 'Opcionális általános keretszerződés PDF-dokumentumként amit el kell fogadni a regisztráció előtt',
'Optional privacy policy as PDF-Document that must be accepted prior to registration'
=> 'Opcionális adatvédelmi nyilatkozat PDF-dokumentumként amit el kell fogadni regisztráció előtt',
'How many people can participate?' => 'Hányan vehetnek részt ezen?',
'There are multiple events for this date and time:' => 'Több esemény is rögzítve van ehhez a dátumhoz és időhöz:',
"Pending (pending)\nPaid (paid)\nCancelled (cancelled)\nUncollectable (uncollectable)"
=> "Függőben (függőben)\nFizetve (fizetve)\nLemondva (lemondva)\nBehajthatatlan (behajthatatlan)",
'One status option per line and formatted as either: Name Name (internal value) Name (internal value) Color Name Color
For example: Open (pending) #F00 Paid at place #F00
The following values must exist once: pending, paid, cancelled, uncollectable'
=> 'Egy státusz opció soronként, a következőképpen formázva: Név Név (belső név) Név (belső név) Szín Név Szín
Például: Nyitott (függő) #F00 Helyszínen fizetve #F00
A következő értékeknek kötelezően szerepelniük kell: függőben, fizetve, lemondva, behajthatatlan',
'Invalid billing status selected' => 'Nem érvényes számlázási státusz kiválasztva',
'Booking-Bill has been saved' => 'Lefoglalás számla létrehozva',
'Booking-Bill position has been created' => 'Lefoglalás számla pozicíó nem lett létrehozva',
'No Booking-Bill position has been created' => 'Lefoglalás számla pozicíó nem lett létrehozva',
'Booking-Bill position has been deleted' => 'Lefoglalás számla pozíció törölve',
'Time (in minutes)' => 'Idő (percekben)',
'Price (in cent)' => 'Ár (forintban)',
'New position' => 'Új pozicíó',
'New position by using the pricing rules for this booking' => 'Új pozicíó az árazási szabályt használva ehhez a foglaláshoz',
'Who?' => 'Ki?',
'Player\'s names' => 'Játékosok nevei',
'Booked by' => 'Lefoglalva',
'User matched by' => 'Felhasználó párosítva',
];
================================================
FILE: data/res/i18n/hu-HU/base.php
================================================
'Vissza',
'Related pages' => 'Kapcsolódó oldalak',
' by %s' => '%s',
' at %s' => '%s',
'On %s' => '%s',
'On last %s' => 'Az utolsón %s',
'On next %s' => 'A következőn %s',
'Tomorrow' => 'Holnap',
'Yesterday' => 'Tegnap',
'%s hours ago' => '%s órával ezelött',
'In %s hours' => '%s órán belül',
'One hour ago' => 'Egy órával ezelött',
'In one hour' => 'Egy órán belül',
'%s minutes ago' => '%s percel ezelött',
'In %s minutes' => '%s percen belül',
'One minute ago' => 'Egy percel ezelött',
'In one minute' => 'Egy percen belül',
'Now' => 'Most',
'Monday' => 'Hétfő',
'Tuesday' => 'Kedd',
'Wednesday' => 'Szerda',
'Thursday' => 'Csütörtök',
'Friday' => 'Péntek',
'Saturday' => 'Szombat',
'Sunday' => 'Vasárnap',
'Second' => 'Másodperc',
'Seconds' => 'Másodperc',
'Minute' => 'Perc',
'Minutes' => 'Perc',
'Hour' => 'Óra',
'Hours' => 'Óra',
'Day' => 'Nap',
'Days' => 'Nap',
'Calendar' => 'Naptár',
'from %s to %s' => '%s -tól %s -ig',
'from' => 'tól',
'%s to %s' => '%s ig %s',
'to' => '-',
'and' => 'és',
'or' => 'vagy',
'for' => 'részére',
'Y-m-d' => 'Év.Hónap.Nap',
'Page not found' => 'Oldal nem található',
'Oops ... something went wrong here' => 'Hoppá ... valami hiba történt',
'This page does not (yet) exist' => 'Ez az oldal (még) nem létezik',
'Please %sdrop us a note%s if you were expecting this page.'
=> 'Kérem %sértesítsen bennünket%s ha ezt az oldalt ha problémát észlelt az oldalon.',
'Back to front page' => 'Vissza a fő oldalra',
'Error' => 'Hiba',
'Please %sdrop us a note%s in case of unexpected error messages, %s so that we can repair them quickly.'
=> 'Kérem %sértesítsen bennünket%sha váratlan hibát észlel, %s hogy minél gyorsabban ki tudjuk javítani.',
'Powered by %s' => '',
'Do your like our service?' => 'Meg van elégedve a szolgáltatásunkkal?',
'Contact & Feedback' => 'Kapcsolat & Visszajelzés',
'Our website' => 'Honlapunk',
'Information about' => 'Információk',
'Book by phone' => 'Telefonos foglalás',
'Imprint' => 'Impresszum',
'Privacy' => 'Adatvédelem',
'You need to activate %sJavaScript%s in you web browser to proceed. If in doubt, switch to another web browser (e.g. Mozilla Firefox).'
=> 'Engedélyezni kell a %sJavaScript%s-et in hogy tovább haladhasson. %s Ha a probléma továbbá is fennáll váltson böngészőt (pl. Mozilla Firefox).',
'Square' => 'Pálya',
'Squares' => 'Pályák',
'Player' => 'Játékos',
'Players' => 'Játékosok',
'Visibility' => 'Láthatóság',
'Quantity' => 'Mennyiség',
];
================================================
FILE: data/res/i18n/hu-HU/booking.php
================================================
'Foglalás',
'%s-Booking' => '%s-Foglalás',
'Single' => 'Egyedi',
'Subscription' => 'Előfizetéses',
'Cancelled' => 'Lemondott',
'Pending' => 'Függőben lévő',
'Paid' => 'Fizetett',
'Uncollectable' => 'Behajthatatlan',
'Public' => 'Nyilvános',
'Private' => 'Privát',
'Only once' => 'Csak egyszer',
'Daily' => 'Napi',
'Every 2 days' => 'Minden 2. nap',
'Every 3 days' => 'Minden 3. nap',
'Every 4 days' => 'Minden 4. nap',
'Every 5 days' => 'Minden 5. nap',
'Every 6 days' => 'Minden 6. nap',
'Weekly' => 'Hetente',
'Every 2 weeks' => 'Minden 2. héten',
'Monthly' => 'Havonta',
'Ambiguous user name "%s" passed (multiple users under this name)'
=> 'Több felhasználó is található ugyanezzel a névvel "%s"',
'This booking does not exist' => 'Ez a foglalás nem létezik',
'This reservation does not exist' => 'Ez a foglalás nem létezik',
'Your %s-booking for %s' => 'Az ön foglalásai %s a %s-hoz',
'we have reserved %s %s, %s for you. Thank you for your booking.'
=> 'Lefoglaltuk önnek %s %s am %s .Köszönjük a foglalást.',
'we have just cancelled %s %s, %s for you.'
=> 'Lemondtuk a foglalását %s %s, %s.',
'%s\'s %s-booking for %s' => '%s\'s %s-foglalás %s',
'%s\'s %s-booking has been cancelled' => '%s\'s %s-foglalás lemondva',
];
================================================
FILE: data/res/i18n/hu-HU/calendar.php
================================================
'Ez a naptár dátum érvénytelen',
'The passed calendar squares are invalid' => 'Ez a pályanaptár érvénytelen',
'Morning' => 'Reggel',
'Afternoon' => 'Délután',
'Past' => 'Múlt',
'Too far' => 'Túl távoli',
'Closed' => 'Zárt',
'Free' => 'Szabad',
'Still free' => 'Még szabad',
'Conflict' => 'Konfliktus',
'Occupied' => 'Foglalt',
'Your Booking' => 'Foglalásai',
'Loading' => 'Töltés',
'Please wait' => 'Kérem várjon',
'Arrival' => 'Érkezés',
'Departure' => 'Távozás',
'Our %s for the time' => 'A mi %s az időhöz',
'Invalid date choice' => 'Érvénytelen dátum választás',
'Persons' => 'Személyek',
];
================================================
FILE: data/res/i18n/hu-HU/frontend.php
================================================
'Ma',
'Date' => 'Dátum',
'Time' => 'Idő',
'Show' => 'Mutasd',
'To book %s, %splease register first%s' => 'A %s foglalásához, %skérem itt regisztráljon%s',
'or simply %s login here' => 'vagy egyszerűen %s lépjen be itt',
'Email address' => 'Email cím',
'Email' => 'Email',
'Phone' => 'Telefon',
'Password' => 'Jelszó',
'Login' => 'Belépés',
'Logout' => 'Kilépés',
'New password' => 'Új jelszó',
'Get additional %shelp and information%s' => 'Több %ssegítség és információ%s kérése',
'Online as %s' => 'Belépve mint %s',
'Administration' => 'Adminisztráció',
'My bookings' => 'Foglalásaim',
'My account' => 'Fiókom',
];
================================================
FILE: data/res/i18n/hu-HU/service.php
================================================
'Rendszer státusz',
'Maintenance' => 'Karbantartás',
'Help' => 'Segítség',
'We are currently working on this page.' => 'Jelenleg ez a lap fejlesztés alatt áll.',
'The system is currently not available' => 'A rendszer jelenleg nem elérhető',
'System maintenance underway' => 'Rendszer karbantartás folyamatban',
'We are back as fast as we can. Promised!' => 'A rendszer hamarosan elérhető!',
'The system is available' => 'A rendszer elérhető',
];
================================================
FILE: data/res/i18n/hu-HU/setup.php
================================================
'ep-3 Foglalási rendszer',
'ep-3 Bookingsystem Setup' => 'ep-3 Foglalási rendszer beállítás',
'imgs/branding/ep3-bs-neg-en.png' => 'imgs/branding/ep3-bs-neg-en.png',
];
================================================
FILE: data/res/i18n/hu-HU/square.php
================================================
'Ez a pálya %s már foglalt',
'%sNote:%s Please read and accept the "%s".' => '%sSegédlet:%s Kérem olvassa el és fogadja el a "%s".',
'%sNote:%s Please read and accept our rules and notes.' => '%sSegédlet:%s Kérem olvassa el és fogadja el a szabályokat és a segédletet.',
'%We are sorry:%s This did not work somehow. Please try again.'
=> '%sSajnáljuk:%s Ez valamiért nem működott. Kérem próbálja meg újra.',
'%sCongratulations:%s Your %s has been booked!' => '%sGratulálunk:%s A ön %s lefoglalva.',
'This booking cannot be cancelled anymore online.' => 'Ezt a foglalást nem lehet online lemondani.',
'Your booking has been %scancelled%s.' => 'Az ön foglalása %slemondva%s.',
'Your %s-booking has been cancelled' => 'Az ön %s-foglalása lemondva',
'Disabled' => 'Letiltva',
'Read-Only' => 'Csak olvasható',
'Enabled' => 'Engedélyezve',
'Unknown' => 'Ismeretlen',
'This square does not exist' => 'Ez a pálya nem létezik',
'This square is currently not available' => 'Ez a pálya jelenleg nem elérhető',
'The passed start date is invalid' => 'A megadott kezdő dátum érvénytelen',
'The passed end date is invalid' => 'A megadott vég dátum érvénytelen',
'The passed start time is invalid' => 'A megadott kezdő idő érvénytelen',
'The passed end time is invalid' => 'A megadott kezdő idő érvénytelen',
'The passed time range is invalid' => 'A megadott idő intervallum érvénytelen',
'The passed time is already over' => 'A megadott idő már elmúlt',
'The passed date is still too far away' => 'A megadott dátum túl messze van',
'You cannot book more than %s minutes at once' => 'Ön nem tud több mint %s percet lefoglalni egyszerre',
'You have no permission to cancel this booking' => 'Önnek nincs jogosultsága lemondani ezt a foglalást',
'You have no permission to cancel this subscription' => 'Önnek nincs jogosultsága lemondani ezt az előfizetést',
'This booking does not contain any distinct reservations' => 'Ez a foglalás nem tartalmaz pontosan kivehető lefoglalásokat',
'This booking does contain multiple distinct reservations (please contact our support)'
=> 'Ez a foglalás nem tartalmaz pontosan kivehető lefoglalásokat, kérjük lépjen kapcsolatba az operátorunkkal',
'incl.' => 'beleértve',
'including' => 'beleértve',
'plus' => 'plus',
'VAT' => 'Áfa',
'Summary of your booking:' => 'A foglalások összegzése:',
'%s items' => '%s példány',
'Total' => 'Összesen',
'Update' => 'Frissítés',
'Please note' => 'Kérjük vegye figyelembe',
'Rules-document' => 'Szabályzat dokumentum',
'this will open in a new window' => 'ez meg fog nyitni egy új ablakot',
'Yes, I have %1$sread and accepted%2$s the "%3$s"' => 'Igen, %1$selolvastam és elfogadtam%2$s a "%3$s"',
'Yes, I have %sread and accepted%s these rules and notes' => 'Igen, elolvastam és elfogadtam %sezeket a szabályokat és segítségeket%s',
'Your booking will be binding.' => 'A foglalása kötelező érvényű lesz.',
'Your booking will be binding, however, you can cancel it up to %s before it takes place.'
=> 'A foglalása kötelező érvényű lesz, azonban lemondhatja a foglalás előtt %s-ig',
'Cancel this booking' => 'Ezen foglalás lemondása',
'Cancel booking' => 'Foglalás lemondása',
'Are you sure you want to cancel this booking?' => 'Biztos benne hogy lemondja ezt a foglalást?',
'Yes, cancel this booking' => 'Igen, lemondom ezt a foglalást',
'No, go back' => 'Nem, vissza',
'This %s is still free.' => 'Ez %s még szabad.',
'This %s is still free for %s %s.' => 'Ez %s még szabad a %s %s-hoz.',
'%s/%s already occupied' => '%s/%s már foglalt',
'You are going to book this %s.' => 'Ön lefoglalja ezt %s.',
'How many %s?' => 'Mennyi %s?',
'Consider our additional offers:' => 'Fontolja meg további ajánlatainkat:',
'per item' => 'cikkenként',
'Continue to summary' => 'Folytatás az összefoglaláshoz',
'Invalid %s-amount choosen' => 'Érvénytelen %s-mennyiség kiválasztva',
'Too many %s for this %s choosen' => 'Túl sok %s van kiválasztva ehhez %s',
'Bookings for this %s are currently not possible online' => 'Online foglalás jelenleg nem lehetséges ehhez %s',
'None' => 'Senki sem',
'Book now' => 'Foglalás most',
'Book more' => 'További foglalás',
'You can %slogin%s or %sregister%s, %s to book this %s' => 'Ön %sbejelentkezhet%s vagy %sregisztrálhat%s, %s hogy lefoglalja a következőt %s',
'This %s has been %sbooked to you%s.' => 'Ez %s le lett foglalva %sönnek%s.',
'This %s is already occupied.' => 'Ez már %s foglalt.',
'%s-Check' => '%s-Ellenőrzés',
'Check if your %s is free for your preferred date.' => 'Ellenőrizze hogy szabad-e %s a kiválasztott időben.',
'Start date' => 'Kezdő dátum',
'End date' => 'Vég dátum',
'Check free %s' => 'Foglaltság ellenőrzése %s',
'Check' => 'Ellenőrzés',
'You need to activate %sJavaScript%s in your web browser to proceed. If in doubt, switch to another web browser (e.g. Mozilla Firefox).'
=> '%sJavaScript%s-et aktiválni kell a böngészőben hogy továbbhaladhasson. Ha még mindig fenáll a probláma váltson böngészőt (pl. Mozilla Firefox).',
'until' => '-',
'with' => 'val',
'Change period:' => 'Időtartam választás:',
'Check new period' => 'Új időtartam ellőrzése',
'The names of the other players are optional' => 'A többi játékos nevének megadása nem kötelező',
'The names of the other players are required' => 'A többi játékos nevének megadása kötelező',
'Player\'s name' => 'Játékos neve',
'and email address' => 'és email címe',
'and phone number' => 'és telefonszáma',
];
================================================
FILE: data/res/i18n/hu-HU/user.php
================================================
'Nincs bejelentkezve',
'You have no permission for this' => 'Ehhez nincs jogosultsága',
'Forgot password?' => 'Elfelejtette a jelszót?',
'Forgot your password?' => 'Elfelejtette a jelszavát?',
'We have just received your request to reset your password.' => 'Megkaptuk a jelszóvisszaállítási kérését.',
'Unfortunately, your account is considered a placeholder and thus cannot login.' => 'Sajnos a felhasználói fiókja foglalva van és ezért nem lehet bejelentkezni.',
'Unfortunately, your account is currently blocked. Please contact us for support.' => 'Sajnos a felhasználói fiókja le van tiltva. Lépjen kapcsolatba velünk további segítségért.',
'Unfortunately, your account has not yet been activated. If you did not receive an activation email yet, you can request a new one here:'
=> 'Sajnos, a felhasználói fiókja még nincs aktiválva. Ha nem kapot aktiválási email-t, akkor itt tud újat kérni:',
'Simply visit the following website to type your new password:' => 'A következő oldalon adhatja meg az új jelszavát:',
'However, you are using a privileged account. For safety, you cannot reset your password this way. Please contact the system support.'
=> 'Emelt jogokkal rendelkező felhasználói fiókja van. Biztonsági okok miatt nem lehet a jelszavát megváltoztatni ilyen módon. Lépjen kapcsolatba velünk.',
'Unfortunately, your account seems somewhat unique, thus we are unsure how to treat it. Mind contacting us?'
=> 'Sajnos a felhasználói fiókjának egyedi problémája van, ezért nem tudjuk hogyan kezelni. Lépjen kapcsolatba velünk.',
'All right, you should receive an email from us soon' => 'Hamarosan fog egy email-t kapni tőlünk',
'if we find a valid user account with this email address' => 'ha találunk egy érvényes felhasználói fiókot ezzel az email címmel',
'Your token to reset your password is invalid or expired. Please request a new email.'
=> 'A jelsző visszaállító kulcs nem érvényes vagy lejárt. Kérem kérjen egy új email-t',
'All right, your password has been changed. You can now log into your account.'
=> 'Jelszava sikeresen megváltoztatva. Most már be tud lépni.',
'New registration waiting for activation' => 'Az új regisztrálása aktiválásra vár',
'A new user has registered to your %s. According to your configuration, this user will not be able to book %s until you manually activate him.'
=> 'Egy új felhasználó regisztrálva lett az ön %s. A beállításai alapján ez a felhasználó nem fog tudni foglalni %s amíg manuálisan nem aktiválja',
'Your registration to the %s %s' => 'A regisztrációja a %s %s - hoz',
"welcome to the %s %s!\r\n\r\nThank you for your registration to our service.\r\n\r\nBefore you can completely use your new user account to book spare %s online, you have to activate it by simply clicking the following link. That's all!\r\n\r\n%s"
=> "Üdvözöljük a %s %s -hoz!\r\n\r\nKöszönjük a regisztrációját.\r\n\r\nMielött foglalni tudna ez új felhasználói fiókjávak %s, aktiválnia kell a következő linken!\r\n\r\n%s",
'Your activation code seems invalid. Please try again.' => 'Az aktivációs kódja nem érvényes. Kérjük próbálja meg újra.',
'You cannot manually activate your account currently' => 'Jelenleg ön nem tudja manuálisan aktiválni a felhasználói fiókját',
'We have just received your request for a new user account activation email.' => 'Megkaptuk az új aktivációs email-re vonatkozó kérését.',
'Unfortunately, your account is considered a placeholder and thus cannot be activated.' => 'Sajnos a felhasználói fiókja foglalva van és ezért nem lehet bejelentkezni.',
"Before you can completely use your new user account to book spare %s online, you have to activate it by simply clicking the following link. That's all!\r\n\r\n%s"
=> "Mielőtt foglalni tudna az új felhasználói fiókjával %s, aktiválnia kell a következő linken!\r\n\r\n%s",
'However, your account has already been activated. You can login whenever you like!'
=> 'A felhasználói fiókja már aktiválva lett. Mostantól bármikor be tud jelentkezni!',
'Your %sphone number%s has been updated' => 'Az ön %stelefonszáma%s frissítve lett',
'New email address at %s %s' => 'Az új email cím %s %s',
"You have just changed your account's email address to this one.\r\n\r\nBefore you can completely use your new email address to book spare %s online again, you have to activate it by simply clicking the following link. That's all!\r\n\r\n%s"
=> "Ön megváltoztatta a felhasználói fiók email címét a következőre.\r\n\r\nMielőtt használni tudja az új email címét foglalásokhoz %s aktiválnia kell a következő linken!\r\n\r\n%s",
'Your %semail address%s has been updated' => 'Az ön %semail címe%s módosítva',
'Your %snotification settings%s have been updated' => 'Az ön %sfigyelmeztetési beállításai%s módosítva',
'Your %spassword%s has been updated' => 'Az ön %sjelszava%s módosítva',
'This is not your correct password' => 'Ez nem a helyes jelszava',
'Your %suser account has been deleted%s. Good bye!' => 'Az ön %sfelhasználói fiókja törlésre került %s. Viszontlátásra!',
'Due to too many login attempts, temporarily blocked until %s' => 'Túl sok sikertelen bejelentkezési kísérlet miatt %-is blokkolásra került',
'This account is considered a placeholder and thus cannot login' => 'Ez a fiók speciális funkcióval bír, emiatt nem lehetséges bejelentkezni',
'Email address and/or password invalid' => 'Az email cím és/vagy jelszó nem érvényes',
'This account is currently blocked' => 'Ez a fiók jelenleg blokkolva van',
'This account has not yet been activated' => 'Ez a fiók még nincs aktiválva',
'Welcome, %s' => 'Üdvözöljük, %s',
'User' => 'Felhasználó',
'Placeholder' => 'Helykitöltés',
'Deleted user' => 'Törölt felhasználó',
'Blocked user' => 'Blokkolt felhasználó',
'Waiting for activation' => 'Aktiválásra vár',
'Enabled user' => 'Engedélyezett felhasználó',
'Assist' => 'Segítő',
'Admin' => 'Adminisztrátor',
'Mr.' => 'Úr',
'Mrs' => 'Asszony',
'Family' => 'Család',
'Firm' => 'Cég',
'May manage users' => 'Kezelhet felhasználókat',
'May manage bookings' => 'Kezelhet foglalásokat',
'May manage events' => 'Kezelhet eseményeket',
'May change configuration' => 'Változtathat beállításokat',
'Can see the admin menu' => 'Láthatja az adminisztrátori menüt',
'Can see the past in calendar' => 'Láthatja az előzményeket naptárban',
'Can see names and data in calendar' => 'Láthatja a neveket és az adatokat a naptárban',
'May create single bookings' => 'Foglalást létrehozhat',
'May cancel single bookings' => 'Foglalást lemondhat',
'May delete single bookings' => 'Foglalást törölhet',
'May create multiple bookings' => 'Többszörös fogalást létrehozhat',
'May cancel multiple bookings' => 'Többszörös foglalást lemondhat',
'May delete multiple bookings' => 'Többszörös foglalást törölhet',
'Request activation mail' => 'Aktivációs email kérése',
'Resend activation email' => 'Aktivációs email újraküldése',
'Were you not happy with our service? Please tell us why you leave. Thank you!'
=> 'Nem volt elégedett a szolgáltatásunkkal? Kérjük mondja meg miért nem. Köszönjük!',
'Delete account' => 'Felhasználó törlése',
'Your current password' => 'Jelenlegi jelszava',
'Your new password' => 'Új jelszava',
'Please provide your email address' => 'Kérjük adja meg az email címét',
'Please type your email address here' => 'Kérjük adja meg itt az email címét',
'Please type your correct email address here' => 'Kérjük ajd meg itt a helyes email címét',
'We could not verify your email provider' => 'Nem tudtuk ellenőrizni az email szolgáltatóját',
'Trash mail addresses are currently blocked - sorry' => 'Kuka email címek jelenleg tiltva vannak - sajnáljuk',
'This email address has already been registered' => 'Ez az email cím már regisztrálva van',
'Both email addresses must be identical' => 'Mindkét email címnek egyeznie kell',
'Both passwords must be identical' => 'Mindkét jelszónak egyeznie kell',
'Please type your password here' => 'Kérjük adja meg a jelszavát itt',
'Please type a new password here' => 'Kérjük adja meg az új jelszavát itt',
'Please type your email address again to prevent typing errors' => 'Kérjük adja meg az email címét ismet a hibák elkerülése érdekében',
'Please type your password again to prevent typing errors' => 'Kérjük adja meg a jelszavát a hibák elkerülése érdekében',
'Please type your new password again to prevent typing errors' => 'Kérjük adja meg a jelszavát ismét a hibák elkerüése érdekében',
'Your new password should be at least %min% characters long' => 'Az új jelszava minimum %min% karakter hosszú kell hogy legyen',
'Notify on bookings and cancellations' => 'Figyelmeztessen foglalásoknál és lemondásoknál',
'We can send you confirmations per email' => 'Tudunk megerősítéseket küldeni email-enként',
'Update phone number' => 'Telefonszám frissítése',
'Update email address' => 'Email cím frissítése',
'Update settings' => 'Beállítások frissítése',
'Update password' => 'Jelszó frissítése',
'Change password' => 'Jelszó megváltoztatása',
'Please type your phone number here' => 'Kérjük adja meg a telefonszámát',
'This phone number is somewhat short ...' => 'Ez a telefonszám túl rövid',
'This phone number contains invalid characters - sorry' => 'Ez a telefonszám érvénytelen karaktereket tartalmaz',
'Your password will be safely encrypted' => 'A jelszó biztonságosan, titkosítva lesz eltárolva',
'Please type your password again' => 'Kérküj adja meg ismét a jelszavát',
'We only use this to inform you about changes to your bookings' => 'Csak arra használjuk ezt, hogy informáljuk önt a foglalások változásárol',
'Salutation' => 'Köszöntés',
'First & Last name' => 'Keresztnév- & Vezetéknév',
'Last name' => 'Vezetéknév',
'Street & Number' => 'Utca és házszám',
'Street number' => 'Házszám',
'Postal code & City' => 'Irányítószám és város',
'City' => 'Város',
'Phone number' => 'Telefonszám',
'Birthday' => 'Születési idő',
'This is optional' => 'Szabadon választható',
'Complete registration' => 'Regisztráció befejezése',
'Please type your name here' => 'Adja meg a nevét',
'Your name is somewhat short ...' => 'A név túl rövid',
'Your name contains invalid characters - sorry' => 'A név nem érvényes karaktereket',
'Your last name is somewhat short ...' => 'A vezetéknév rövid',
'Your last name contains invalid characters - sorry' => 'A vezetéknév érvénytelen karaktereket tartalmaz',
'Please type your street name here' => 'Adja meg az utca nevet itt',
'This street name is somewhat short ...' => 'Az utca név rövid',
'This street name contains invalid characters - sorry' => 'Az utca név érvénytelen karaktereket tartalmaz',
'Please type your street number here' => 'Ajda meg a házszámot itt',
'This street number contains invalid characters - sorry' => 'Az házszám érvénytelen karaktereket tartalmaz',
'Please type your postal code here' => 'Adja meg az irányítószámot itt',
'Please provide a correct postal code' => 'Érvénytelen irányítószám',
'Please type your city here' => 'Adja meg a város nevét itt',
'This city name is somewhat short ...' => 'A város neve rövid',
'This city name contains invalid characters - sorry' => 'A város neve érvénytelen karaktereket tartalmaz',
'Please leave this field empty' => 'Kérem hagyja üresen ezt a mezőt',
'Please register about our website only' => 'Kérjük csak a regisztrációs formulákat használja',
'You were too quick for our system! Please wait some seconds and try again. Thank you!' => 'Kérem várjon pár másodpercet és próbálja újra. Köszönjük!',
'User name too short' => 'A felhasználó név túl rövid',
'This user does not exist' => 'Ez a felhasználó nem létezik',
'You have no imminent bookings.' => 'Önnek nincs aktuális foglalása',
'You have not booked any %s yet.' => 'Ön nem foglalt idáig %s -t.',
'You have already booked one %s.' => 'Ön már foglalt egy %s -t.',
'You have already booked %s %s.' => 'Ön már foglalt %s %s.',
'If you did not receive an activation email from us after registration, you can request a new one here.'
=> 'Ha nem kapott aktivációs email a regisztrálás után, akkor itt tud újat kérni.',
'Therefore, please type the email adress you used for registration.' => 'Ezért kérem adja meg az email címet amit a regisztrációhoz használt.',
'Your user account has been activated. You can now login with your email address and password. Have fun!'
=> 'A felhasználói fiókja aktiválva lett. Most már be tud jelentkezni az email címével és a jelszavával!',
'Now you can type a new password for your user account.' => 'Most meg tudja adni az új jelszavát a felhasználói fiókjához.',
'No need to be sad. You may simply type your email address here and you will soon be able to choose a new password.'
=> 'Egyszerűen adja meg az email címét és hamarosan új jelszót tud választani',
'Registration complete' => 'Regisztráció kész',
'The registration is complete and your user account has been created successfully'
=> 'A regisztráció kész és a felhasználói fiók sikeresen létrehozva',
'You can now login with your email address and password. Have fun!'
=> 'Most már be tud jelentkezni az email címével és a jelszavával!',
'However, your user account is %snot yet activated%s.'
=> 'A felhasználói fiókja %smég nem aktivált%s.',
'This will happen during a quick manual verification of your user account data.'
=> 'Ez meg fog történni egy gyors manuális felhasználói fiók ellenőrzés során.',
'Please be patient, this will be done soon.'
=> 'Kérem legyen türelemmel, hamarosan kész.',
'The only step remaining is to %sactivate your user account%s.'
=> 'Ez utolsó hátralevő lépés %shogy aktiválhassa a felhasználói fiókját%s.',
'For this, we just sent you an email with an activation link within. Please check.'
=> 'Elküldtünk egy aktivációs email-t.Kérjük ellenőrizze.',
'If you did not receive an email from us, you can always %srequest a new one%s.'
=> 'Ha nem kapta meg az aktivációs email-t %sakkor tud újat kérni%s.',
'Register now' => 'Regisztrálás',
'Registration' => 'Regisztráció',
'Activation' => 'Aktiválás',
'Welcome to our %s' => 'Üdvözöljük a %s-ben',
'You probably guessed it: To use our service, that is to book spare %s online, you need to create your own user account first.'
=> 'Bizonyára már kitalálta: Hogy szolgáltatásunkat online igénybe tudja venni, először regisztrálnia kell.',
'The registration is of course free of cost and nonbinding.' => 'Természetesen a regisztráció ingyenes és nem kötelez semmire, valamint bármikor megszüntetheti.',
'We are very sorry, but the registration is currently not possible.' => 'Sajnáljuk a regisztrálás jelenleg nem lehetséges.',
'Login data' => 'Belépési adatok',
'Account data' => 'Felhasználói adatok',
'Personal data' => 'Személyes adatok',
'I have read and accept the %1$sprivacy policy%2$s' => 'Elolvastam és elfogadtam az%1$sadatvédelmi nyilatkozatot%2$s',
'please inform us about changes, so we can update this data' => 'kérem értesítsen bennünket a változtatásokról, hogy frissíteni tudjuk az adatokat',
'Note: You need to activate your account again if you update your email address.'
=> 'Ismételten aktiválnia kell a felhasználói fiókját ha megváltoztatta az email cimét.',
'Update notifications' => 'Figyelmeztetések frissítése',
'Delete this account' => 'Felhasználói fiók törlése',
'Bye, %s' => 'Viszontlátásra, %s',
'If you have already registered, you can login here with your email address and start booking %s.'
=> 'Ha már regisztrált akkor itt tud bejelentkeztni az email címével és kezdhet foglalni %s.',
'Bill' => 'Számla',
'Booking-Bill' => 'Foglalás számla',
'I agree to %s' => 'Egyetértek a %s -el',
'Please agree to this' => 'Kérjük fogadja el',
/* Email */
'Dear' => 'Kedves',
'Hello' => 'Helló',
'This was an automated message from the system.' => 'Ez egy rendszerünk által előállított automatikus üzenet volt.',
'Originally sent to %s (%s).' => 'Eredetileg elküldve erre a címre %s (%s).',
'Sincerely' => 'Üdvözlettel',
'Your' => 'Az ön',
];
================================================
FILE: data/res/i18n-custom/de-DE/.gitignore
================================================
*
!.gitignore
================================================
FILE: data/res/i18n-custom/fr-FR/.gitignore
================================================
*
!.gitignore
================================================
FILE: data/res/i18n-custom/hu-HU/.gitignore
================================================
*
!.gitignore
================================================
FILE: data/session/.gitignore
================================================
*
!.gitignore
================================================
FILE: index.php
================================================
array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
}
================================================
FILE: module/Backend/config/module.config.php
================================================
array(
'routes' => array(
'backend' => array(
'type' => 'Literal',
'options' => array(
'route' => '/backend',
'defaults' => array(
'controller' => 'Backend\Controller\Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'user' => array(
'type' => 'Literal',
'options' => array(
'route' => '/user',
'defaults' => array(
'controller' => 'Backend\Controller\User',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'edit' => array(
'type' => 'Segment',
'options' => array(
'route' => '/edit[/:uid]',
'defaults' => array(
'action' => 'edit',
),
'constraints' => array(
'uid' => '[0-9]+',
),
),
),
'delete' => array(
'type' => 'Segment',
'options' => array(
'route' => '/delete/:uid',
'defaults' => array(
'action' => 'delete',
),
'constraints' => array(
'uid' => '[0-9]+',
),
),
),
'interpret' => array(
'type' => 'Literal',
'options' => array(
'route' => '/interpret',
'defaults' => array(
'action' => 'interpret',
),
),
),
'stats' => array(
'type' => 'Literal',
'options' => array(
'route' => '/stats',
'defaults' => array(
'action' => 'stats',
),
),
),
),
),
'booking' => array(
'type' => 'Literal',
'options' => array(
'route' => '/booking',
'defaults' => array(
'controller' => 'Backend\Controller\Booking',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'edit' => array(
'type' => 'Literal',
'options' => array(
'route' => '/edit',
'defaults' => array(
'action' => 'edit',
),
),
'may_terminate' => true,
'child_routes' => array(
'range' => array(
'type' => 'Segment',
'options' => array(
'route' => '/range/:bid',
'defaults' => array(
'action' => 'editRange',
),
),
),
),
),
'delete' => array(
'type' => 'Segment',
'options' => array(
'route' => '/delete/:rid',
'defaults' => array(
'action' => 'delete',
),
'constraints' => array(
'rid' => '[0-9]+',
),
),
),
'stats' => array(
'type' => 'Literal',
'options' => array(
'route' => '/stats',
'defaults' => array(
'action' => 'stats',
),
),
),
'bills' => array(
'type' => 'Segment',
'options' => array(
'route' => '/bills/:bid',
'defaults' => array(
'action' => 'bills',
),
'constraints' => array(
'bid' => '[0-9]+',
),
),
),
'players' => array(
'type' => 'Segment',
'options' => array(
'route' => '/players/:bid',
'defaults' => array(
'action' => 'players',
),
'constraints' => array(
'bid' => '[0-9]+',
),
),
),
),
),
'event' => array(
'type' => 'Literal',
'options' => array(
'route' => '/event',
'defaults' => array(
'controller' => 'Backend\Controller\Event',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'edit' => array(
'type' => 'Segment',
'options' => array(
'route' => '/edit[/:eid]',
'defaults' => array(
'action' => 'edit',
),
'constraints' => array(
'eid' => '[0-9]+',
),
),
),
'edit-choice' => array(
'type' => 'Literal',
'options' => array(
'route' => '/edit-choice',
'defaults' => array(
'action' => 'editChoice',
),
),
),
'delete' => array(
'type' => 'Segment',
'options' => array(
'route' => '/delete/:eid',
'defaults' => array(
'action' => 'delete',
),
'constraints' => array(
'eid' => '[0-9]+',
),
),
),
'stats' => array(
'type' => 'Literal',
'options' => array(
'route' => '/stats',
'defaults' => array(
'action' => 'stats',
),
),
),
),
),
'config' => array(
'type' => 'Literal',
'options' => array(
'route' => '/config',
'defaults' => array(
'controller' => 'Backend\Controller\Config',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'text' => array(
'type' => 'Literal',
'options' => array(
'route' => '/text',
'defaults' => array(
'action' => 'text',
),
),
),
'info' => array(
'type' => 'Literal',
'options' => array(
'route' => '/info',
'defaults' => array(
'action' => 'info',
),
),
),
'help' => array(
'type' => 'Literal',
'options' => array(
'route' => '/help',
'defaults' => array(
'action' => 'help',
),
),
),
'square' => array(
'type' => 'Literal',
'options' => array(
'route' => '/square',
'defaults' => array(
'controller' => 'Backend\Controller\ConfigSquare',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'edit' => array(
'type' => 'Segment',
'options' => array(
'route' => '/edit[/:sid]',
'defaults' => array(
'action' => 'edit',
),
'constraints' => array(
'sid' => '[0-9]+',
),
),
'may_terminate' => true,
'child_routes' => array(
'info' => array(
'type' => 'Literal',
'options' => array(
'route' => '/info',
'defaults' => array(
'action' => 'editInfo',
),
),
),
),
),
'pricing' => array(
'type' => 'Literal',
'options' => array(
'route' => '/pricing',
'defaults' => array(
'action' => 'pricing',
),
),
),
'product' => array(
'type' => 'Literal',
'options' => array(
'route' => '/product',
'defaults' => array(
'action' => 'product',
),
),
'may_terminate' => true,
'child_routes' => array(
'edit' => array(
'type' => 'Segment',
'options' => array(
'route' => '/edit[/:spid]',
'defaults' => array(
'action' => 'productEdit',
),
'constraints' => array(
'spid' => '[0-9]+',
),
),
),
'delete' => array(
'type' => 'Segment',
'options' => array(
'route' => '/delete/:spid',
'defaults' => array(
'action' => 'productDelete',
),
'constraints' => array(
'spid' => '[0-9]+',
),
),
),
),
),
'coupon' => array(
'type' => 'Literal',
'options' => array(
'route' => '/coupon',
'defaults' => array(
'action' => 'coupon',
),
),
),
'delete' => array(
'type' => 'Segment',
'options' => array(
'route' => '/delete/:sid',
'defaults' => array(
'action' => 'delete',
),
'constraints' => array(
'sid' => '[0-9]+',
),
),
),
),
),
'behaviour' => array(
'type' => 'Literal',
'options' => array(
'route' => '/behaviour',
'defaults' => array(
'action' => 'behaviour',
),
),
'may_terminate' => true,
'child_routes' => array(
'rules' => array(
'type' => 'Literal',
'options' => array(
'route' => '/rules',
'defaults' => array(
'action' => 'behaviourRules',
),
),
),
'status-colors' => array(
'type' => 'Literal',
'options' => array(
'route' => '/status-colors',
'defaults' => array(
'action' => 'behaviourStatusColors',
),
),
),
),
),
),
),
),
),
),
),
'controllers' => array(
'invokables' => array(
'Backend\Controller\Index' => 'Backend\Controller\IndexController',
'Backend\Controller\User' => 'Backend\Controller\UserController',
'Backend\Controller\Booking' => 'Backend\Controller\BookingController',
'Backend\Controller\Event' => 'Backend\Controller\EventController',
'Backend\Controller\Config' => 'Backend\Controller\ConfigController',
'Backend\Controller\ConfigSquare' => 'Backend\Controller\ConfigSquareController',
),
),
'controller_plugins' => array(
'invokables' => array(
'BackendBookingDetermineFilters' => 'Backend\Controller\Plugin\Booking\DetermineFilters',
'BackendUserDetermineFilters' => 'Backend\Controller\Plugin\User\DetermineFilters',
),
'factories' => array(
'BackendBookingCreate' => 'Backend\Controller\Plugin\Booking\CreateFactory',
'BackendBookingDetermineParams' => 'Backend\Controller\Plugin\Booking\DetermineParamsFactory',
'BackendBookingUpdate' => 'Backend\Controller\Plugin\Booking\UpdateFactory',
),
),
'service_manager' => array(
'factories' => array(
'Backend\Service\MailService' => 'Backend\Service\MailServiceFactory',
),
),
'form_elements' => array(
'factories' => array(
'Backend\Form\Booking\EditForm' => 'Backend\Form\Booking\EditFormFactory',
'Backend\Form\Event\EditForm' => 'Backend\Form\Event\EditFormFactory',
'Backend\Form\ConfigSquare\EditProductForm' => 'Backend\Form\ConfigSquare\EditProductFormFactory',
'Backend\Form\User\EditForm' => 'Backend\Form\User\EditFormFactory',
),
),
'view_helpers' => array(
'invokables' => array(
'BackendBookingsFormat' => 'Backend\View\Helper\Booking\BookingsFormat',
'BackendEventsFormat' => 'Backend\View\Helper\Event\EventsFormat',
'BackendSquareProductsFormat' => 'Backend\View\Helper\Square\ProductsFormat',
'BackendSquareFormat' => 'Backend\View\Helper\Square\SquareFormat',
'BackendSquaresFormat' => 'Backend\View\Helper\Square\SquaresFormat',
'BackendUserFilterHelp' => 'Backend\View\Helper\User\FilterHelp',
'BackendUserFormat' => 'Backend\View\Helper\User\UserFormat',
'BackendUsersFormat' => 'Backend\View\Helper\User\UsersFormat',
'BackendInfo' => 'Backend\View\Helper\Info',
),
'factories' => array(
'BackendBookingFormat' => 'Backend\View\Helper\Booking\BookingFormatFactory',
'BackendEventFormat' => 'Backend\View\Helper\Event\EventFormatFactory',
'BackendSquareProductFormat' => 'Backend\View\Helper\Square\ProductFormatFactory',
),
),
'view_manager' => array(
'template_path_stack' => array(
__DIR__ . '/../view',
),
'strategies' => array(
'ViewJsonStrategy',
),
),
);
================================================
FILE: module/Backend/src/Backend/Controller/BookingController.php
================================================
authorize('admin.booking');
$serviceManager = @$this->getServiceLocator();
$bookingManager = $serviceManager->get('Booking\Manager\BookingManager');
$reservationManager = $serviceManager->get('Booking\Manager\ReservationManager');
$userManager = $serviceManager->get('User\Manager\UserManager');
$bookings = array();
$reservations = array();
$dateStart = $this->params()->fromQuery('date-start');
$dateEnd = $this->params()->fromQuery('date-end');
$search = $this->params()->fromQuery('search');
if ($dateStart) {
$dateStart = new \DateTime($dateStart);
}
if ($dateEnd) {
$dateEnd = new \DateTime($dateEnd);
}
if (($dateStart && $dateEnd) || $search) {
$filters = $this->backendBookingDetermineFilters($search);
try {
$limit = 1000;
if ($dateStart && $dateEnd) {
$reservations = $reservationManager->getInRange($dateStart, $dateEnd, $limit);
$bookings = $bookingManager->getByReservations($reservations, $filters['filters']);
} else {
$bookings = $bookingManager->getBy($filters['filters'], null, $limit);
}
$bookings = $this->complexFilterBookings($bookings, $filters);
$reservations = $reservationManager->getByBookings($bookings);
$userManager->getByBookings($bookings);
} catch (\RuntimeException $e) {
$bookings = array();
$reservations = array();
}
}
return array(
'bookings' => $bookings,
'reservations' => $reservations,
'dateStart' => $dateStart,
'dateEnd' => $dateEnd,
'search' => $search,
);
}
protected function complexFilterBookings($bookings, $filters)
{
$serviceManager = @$this->getServiceLocator();
foreach ($filters['filterParts'] as $filterPart) {
// Filter for billing total
if ($filterPart[0] == str_replace(' ', '_', strtolower($this->t('Billing total')))) {
$bookingBillManager = $serviceManager->get('Booking\Manager\Booking\BillManager');
$bookingBillManager->getByBookings($bookings);
$bookings = array_filter($bookings, function(Booking $booking) use ($filterPart) {
switch ($filterPart[1]) {
case '=':
return $booking->getExtra('bills_total') == (int) $filterPart[2];
case '>':
return $booking->getExtra('bills_total') > (int) $filterPart[2];
case '<':
return $booking->getExtra('bills_total') < (int) $filterPart[2];
default:
return false;
}
});
}
}
return $bookings;
}
public function editAction()
{
$sessionUser = $this->authorize('admin.booking, calendar.see-data');
$params = $this->backendBookingDetermineParams(true);
$reservation = $booking = null;
if (! ($this->getRequest()->isPost() || $this->params()->fromQuery('force') == 'new')) {
switch (count($params['reservations'])) {
case 0:
break;
case 1:
$reservation = current($params['reservations']);
$booking = $reservation->getExtra('booking');
if ($booking->get('status') == 'subscription') {
if (! $params['editMode']) {
return $this->forward()->dispatch('Backend\Controller\Booking', ['action' => 'editMode', 'params' => $params]);
}
}
break;
default:
return $this->forward()->dispatch('Backend\Controller\Booking', ['action' => 'editChoice', 'params' => $params]);
}
}
$serviceManager = @$this->getServiceLocator();
$formElementManager = $serviceManager->get('FormElementManager');
$editForm = $formElementManager->get('Backend\Form\Booking\EditForm');
if ($this->getRequest()->isPost()) {
$editForm->setData($this->params()->fromPost());
if ($editForm->isValid()) {
$d = $editForm->getData();
/* Process form (note, that reservation and booking are not available here) */
if ($d['bf-rid']) {
/* Update booking/reservation */
$savedBooking = $this->backendBookingUpdate($d['bf-rid'], $d['bf-user'], $d['bf-time-start'], $d['bf-time-end'], $d['bf-date-start'],
$d['bf-sid'], $d['bf-status-billing'], $d['bf-quantity'], $d['bf-notes'], $params['editMode']);
} else {
/* Create booking/reservation */
$savedBooking = $this->backendBookingCreate($d['bf-user'], $d['bf-time-start'], $d['bf-time-end'], $d['bf-date-start'], $d['bf-date-end'],
$d['bf-repeat'], $d['bf-sid'], $d['bf-status-billing'], $d['bf-quantity'], $d['bf-notes'], $sessionUser->get('alias'));
}
$this->flashMessenger()->addSuccessMessage('Booking has been saved');
if ($this->params()->fromPost('bf-edit-user')) {
return $this->redirect()->toRoute('backend/user/edit', ['uid' => $savedBooking->get('uid')]);
} else if ($this->params()->fromPost('bf-edit-bills')) {
return $this->redirect()->toRoute('backend/booking/bills', ['bid' => $savedBooking->get('bid')]);
} else {
return $this->redirect()->toRoute('frontend');
}
}
} else {
if ($booking) {
$user = $booking->needExtra('user');
$editForm->setData(array(
'bf-rid' => $reservation->get('rid'),
'bf-user' => $user->need('alias') . ' (' . $user->need('uid') . ')',
'bf-sid' => $booking->get('sid'),
'bf-status-billing' => $booking->get('status_billing'),
'bf-quantity' => $booking->get('quantity'),
'bf-notes' => $booking->getMeta('notes'),
));
if ($booking->get('status') == 'subscription' && $params['editMode'] == 'booking') {
$editForm->setData(array(
'bf-time-start' => substr($booking->getMeta('time_start', $reservation->get('time_start')), 0, 5),
'bf-time-end' => substr($booking->getMeta('time_end', $reservation->get('time_end')), 0, 5),
'bf-date-start' => $this->dateFormat($booking->getMeta('date_start', $reservation->get('date')), \IntlDateFormatter::MEDIUM),
'bf-date-end' => $this->dateFormat($booking->getMeta('date_end', $reservation->get('date')), \IntlDateFormatter::MEDIUM),
'bf-repeat' => $booking->getMeta('repeat'),
));
} else {
$editForm->setData(array(
'bf-time-start' => substr($reservation->get('time_start'), 0, 5),
'bf-time-end' => substr($reservation->get('time_end'), 0, 5),
'bf-date-start' => $this->dateFormat($reservation->get('date'), \IntlDateFormatter::MEDIUM),
'bf-date-end' => $this->dateFormat($reservation->get('date'), \IntlDateFormatter::MEDIUM),
));
}
} else {
$timeEnd = $params['dateTimeEnd']->format('H:i');
if ($timeEnd == '00:00') {
$timeEnd = '24:00';
}
$editForm->setData(array(
'bf-sid' => $params['square']->get('sid'),
'bf-date-start' => $this->dateFormat($params['dateTimeStart'], \IntlDateFormatter::MEDIUM),
'bf-date-end' => $this->dateFormat($params['dateTimeEnd'], \IntlDateFormatter::MEDIUM),
'bf-time-start' => $params['dateTimeStart']->format('H:i'),
'bf-time-end' => $timeEnd,
));
}
}
if ($booking && $booking->getMeta('player-names')) {
$editForm->get('bf-quantity')->setLabel(sprintf('%s (%s)',
$this->translate('Number of players'),
$this->url()->fromRoute('backend/booking/players', ['bid' => $booking->need('bid')]),
$this->translate('Who?')));
$editForm->get('bf-quantity')->setLabelOption('disable_html_escape', true);
$playerNameNotes = '';
$playerNames = $booking->getMeta('player-names');
if ($playerNames) {
$playerNamesUnserialized = @unserialize($booking->getMeta('player-names'));
if ($playerNamesUnserialized && is_array($playerNamesUnserialized)) {
foreach ($playerNamesUnserialized as $i => $playerName) {
$playerNameNotes .= sprintf('
',
$userName);
/* Date and time col */
$date = new \DateTime($reservation->get('date'));
$fullDate = $view->dateFormat($date, \IntlDateFormatter::FULL);
$fullDateParts = explode(', ', $fullDate);
$html .= sprintf('
This tool will help you initially setup the database.
In the first step, we will try to create all the MySQL tables the system needs by executing the
/data/db/ep3-bs.sql file on the = $this->config('db.dsn') ?> database.
However, if that fails, you can easily install/import it manually.
= $this->message($this->importMessage, 'info') ?>
import): ?>
= $this->message('Database tables have been created', 'success') ?>
= $this->message('Database tables have not been created', 'error') ?>
But no need to be sad! Just import the entire /data/db/ep3-bs.sql file
into your database (e.g. via phpMyAdmin).
In the second step, we will insert a minimum amount of records to make the system work.
All other configuration can be performed via the system backend itself.
= sprintf($this->t('You need to activate %sJavaScript%s in your web browser to proceed. If in doubt, switch to another web browser (e.g. Mozilla Firefox).'), '', '', ' ') ?>
================================================
FILE: module/User/Module.php
================================================
array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
}
================================================
FILE: module/User/config/module.config.php
================================================
array(
'routes' => array(
'user' => array(
'type' => 'Literal',
'options' => array(
'route' => '/user',
),
'may_terminate' => false,
'child_routes' => array(
'login' => array(
'type' => 'Literal',
'options' => array(
'route' => '/login',
'defaults' => array(
'controller' => 'User\Controller\Session',
'action' => 'login',
),
),
),
'logout' => array(
'type' => 'Literal',
'options' => array(
'route' => '/logout',
'defaults' => array(
'controller' => 'User\Controller\Session',
'action' => 'logout',
),
),
),
'password' => array(
'type' => 'Literal',
'options' => array(
'route' => '/password',
'defaults' => array(
'controller' => 'User\Controller\Account',
'action' => 'password',
),
),
),
'password-reset' => array(
'type' => 'Literal',
'options' => array(
'route' => '/password-reset',
'defaults' => array(
'controller' => 'User\Controller\Account',
'action' => 'passwordReset',
),
),
),
'registration' => array(
'type' => 'Literal',
'options' => array(
'route' => '/registration',
'defaults' => array(
'controller' => 'User\Controller\Account',
'action' => 'registration',
),
),
),
'registration-confirmation' => array(
'type' => 'Literal',
'options' => array(
'route' => '/registration-confirmation',
'defaults' => array(
'controller' => 'User\Controller\Account',
'action' => 'registrationConfirmation',
),
),
),
'activation' => array(
'type' => 'Literal',
'options' => array(
'route' => '/activation',
'defaults' => array(
'controller' => 'User\Controller\Account',
'action' => 'activation',
),
),
),
'activation-resend' => array(
'type' => 'Literal',
'options' => array(
'route' => '/activation-resend',
'defaults' => array(
'controller' => 'User\Controller\Account',
'action' => 'activationResend',
),
),
),
'bookings' => array(
'type' => 'Literal',
'options' => array(
'route' => '/bookings',
'defaults' => array(
'controller' => 'User\Controller\Account',
'action' => 'bookings',
),
),
'may_terminate' => true,
'child_routes' => array(
'bills' => array(
'type' => 'Segment',
'options' => array(
'route' => '/bills/:bid',
'defaults' => array(
'controller' => 'User\Controller\Account',
'action' => 'bills',
),
'constraints' => array(
'bid' => '[0-9]+',
),
),
),
),
),
'settings' => array(
'type' => 'Literal',
'options' => array(
'route' => '/settings',
'defaults' => array(
'controller' => 'User\Controller\Account',
'action' => 'settings',
),
),
),
),
),
),
),
'controllers' => array(
'invokables' => array(
'User\Controller\Session' => 'User\Controller\SessionController',
'User\Controller\Account' => 'User\Controller\AccountController',
),
),
'controller_plugins' => array(
'factories' => array(
'Authorize' => 'User\Controller\Plugin\AuthorizeFactory',
),
),
'service_manager' => array(
'factories' => array(
'User\Manager\UserManager' => 'User\Manager\UserManagerFactory',
'User\Manager\UserSessionManager' => 'User\Manager\UserSessionManagerFactory',
'User\Table\UserMetaTable' => 'User\Table\UserMetaTableFactory',
'User\Table\UserTable' => 'User\Table\UserTableFactory',
'User\Service\MailService' => 'User\Service\MailServiceFactory',
'Zend\Session\Config\ConfigInterface' => 'Zend\Session\Service\SessionConfigFactory',
'Zend\Session\SessionManager' => 'Zend\Session\Service\SessionManagerFactory',
),
),
'form_elements' => array(
'factories' => array(
'User\Form\EditEmailForm' => 'User\Form\EditEmailFormFactory',
'User\Form\RegistrationForm' => 'User\Form\RegistrationFormFactory',
),
),
'view_helpers' => array(
'factories' => array(
'UserLastBookings' => 'User\View\Helper\LastBookingsFactory',
),
),
'view_manager' => array(
'template_path_stack' => array(
__DIR__ . '/../view',
),
),
);
================================================
FILE: module/User/src/User/Authentication/Result.php
================================================
extra[$key] = $value;
}
/**
* Gets an extra value from this result.
*
* @param string $key
* @return mixed
*/
public function getExtra($key)
{
return $this->extra[$key] ?? null;
}
}
================================================
FILE: module/User/src/User/Controller/AccountController.php
================================================
getServiceLocator();
$formElementManager = $serviceManager->get('FormElementManager');
$passwordForm = $formElementManager->get('User\Form\PasswordForm');
$passwordMessage = null;
if ($this->getRequest()->isPost()) {
$passwordForm->setData($this->params()->fromPost());
if ($passwordForm->isValid()) {
$passwordData = $passwordForm->getData();
$userManager = $serviceManager->get('User\Manager\UserManager');
$user = current( $userManager->getBy(array('email' => $passwordData['pf-email'])) );
if ($user) {
$mailMessage = $this->t('We have just received your request to reset your password.') . "\r\n\r\n";
switch ($user->need('status')) {
case 'placeholder':
$mailMessage .= $this->t('Unfortunately, your account is considered a placeholder and thus cannot login.');
break;
case 'blocked':
$mailMessage .= $this->t('Unfortunately, your account is currently blocked. Please contact us for support.');
break;
case 'disabled':
$mailMessage .= $this->t('Unfortunately, your account has not yet been activated. If you did not receive an activation email yet, you can request a new one here:') . "\r\n\r\n";
$mailMessage .= $this->url()->fromRoute('user/activation-resend', [], ['force_canonical' => true]);
break;
case 'enabled':
$resetCode = base64_encode( substr($user->need('pw'), 16, 8) );
$mailMessage .= $this->t('Simply visit the following website to type your new password:') . "\r\n\r\n";
$mailMessage .= $this->url()->fromRoute('user/password-reset', [], ['query' => ['id' => $user->need('uid'), 'code' => $resetCode], 'force_canonical' => true]);
break;
case 'assist':
case 'admin':
$mailMessage .= $this->t('However, you are using a privileged account. For safety, you cannot reset your password this way. Please contact the system support.');
break;
default:
$mailMessage .= $this->t('Unfortunately, your account seems somewhat unique, thus we are unsure how to treat it. Mind contacting us?');
break;
}
$userMailService = $serviceManager->get('User\Service\MailService');
$userMailService->send($user, $this->t('Forgot your password?'), $mailMessage);
}
}
$passwordForm->get('pf-email')->setValue('');
$passwordMessage = sprintf('%s
(%s)
',
$this->t('All right, you should receive an email from us soon'),
$this->t('if we find a valid user account with this email address'));
}
return array(
'passwordForm' => $passwordForm,
'passwordMessage' => $passwordMessage,
);
}
public function passwordResetAction()
{
$resetUid = $this->params()->fromQuery('id');
$resetCode = $this->params()->fromQuery('code');
if (! (is_numeric($resetUid) && $resetUid > 0 && preg_match('/^[a-zA-Z0-9\+\/\=]+$/', $resetCode))) {
throw new RuntimeException('Your token to reset your password is invalid or expired. Please request a new email.');
}
$serviceManager = @$this->getServiceLocator();
$userManager = $serviceManager->get('User\Manager\UserManager');
$user = $userManager->get($resetUid, false);
if (! $user) {
throw new RuntimeException('Your token to reset your password is invalid or expired. Please request a new email.');
}
$actualResetCode = base64_encode( substr($user->need('pw'), 16, 8) );
if ($resetCode != $actualResetCode) {
throw new RuntimeException('Your token to reset your password is invalid or expired. Please request a new email.');
}
$formElementManager = $serviceManager->get('FormElementManager');
$resetForm = $formElementManager->get('User\Form\PasswordResetForm');
$resetMessage = null;
if ($this->getRequest()->isPost()) {
$resetForm->setData($this->params()->fromPost());
if ($resetForm->isValid()) {
$resetData = $resetForm->getData();
$bcrypt = new Bcrypt();
$bcrypt->setCost(6);
$user->set('pw', $bcrypt->create($resetData['prf-pw1']));
$user->set('last_activity', date('Y-m-d H:i:s'));
$user->set('last_ip', $_SERVER['REMOTE_ADDR']);
$userManager->save($user);
$resetMessage = 'All right, your password has been changed. You can now log into your account.';
}
}
return array(
'resetUid' => $resetUid,
'resetCode' => $resetCode,
'resetForm' => $resetForm,
'resetMessage' => $resetMessage,
);
}
public function registrationAction()
{
$serviceManager = @$this->getServiceLocator();
$formElementManager = $serviceManager->get('FormElementManager');
$registrationForm = $formElementManager->get('User\Form\RegistrationForm');
if ($this->getRequest()->isPost() && $this->option('service.user.registration') == 'true') {
$registrationForm->setData($this->params()->fromPost());
if ($registrationForm->isValid()) {
$registrationData = $registrationForm->getData();
$meta = array();
$meta['gender'] = $registrationData['rf-gender'];
if (isset($registrationData['rf-lastname']) && $registrationData['rf-lastname']) {
$meta['firstname'] = ucfirst($registrationData['rf-firstname']);
$meta['lastname'] = ucfirst($registrationData['rf-lastname']);
$alias = $meta['firstname'] . ' ' . $meta['lastname'];
} else {
$meta['name'] = $registrationData['rf-firstname'];
if ($meta['gender'] == 'male' || $meta['gender'] == 'female' || $meta['gender'] == 'family') {
$meta['name'] = ucfirst($meta['name']);
}
$alias = $meta['name'];
}
$meta['street'] = $registrationData['rf-street'] . ' ' . $registrationData['rf-number'];
$meta['zip'] = $registrationData['rf-zip'];
$meta['city'] = $registrationData['rf-city'];
$meta['phone'] = $registrationData['rf-phone'];
if (! (isset($registrationData['rf-birthdate']) && preg_match('/^([ \,\-\.0-9\x{00c0}-\x{01ff}a-zA-Z]){4,}$/u', $registrationData['rf-birthdate']))) {
$registrationData['rf-birthdate'] = null;
}
if (isset($registrationData['rf-birthdate']) && $registrationData['rf-birthdate']) {
$meta['birthdate'] = $registrationData['rf-birthdate'];
}
$meta['locale'] = $this->config('i18n.locale');
if ($this->option('service.user.activation') == 'immediate') {
$status = 'enabled';
} else {
$status = 'disabled';
}
$userManager = $serviceManager->get('User\Manager\UserManager');
$user = $userManager->create($alias, $status, $registrationData['rf-email1'], $registrationData['rf-pw1'], $meta);
$user->set('last_ip', $_SERVER['REMOTE_ADDR']);
$userManager->save($user);
/* Send confirmation email to administration for manual activation */
if ($this->option('service.user.activation') == 'manual-email') {
$backendMailService = $serviceManager->get('Backend\Service\MailService');
$backendMailService->send(
$this->t('New registration waiting for activation'),
sprintf($this->t('A new user has registered to your %s. According to your configuration, this user will not be able to book %s until you manually activate him.'),
$this->option('service.name.full', false), $this->option('subject.square.type.plural', false)));
}
/* Send confirmation email to user for activation */
if ($this->option('service.user.activation') == 'email') {
/* Activation code is "created" hash */
$activationCode = urlencode( sha1($user->need('created')) );
$activationLink = $this->url()->fromRoute('user/activation', [], ['query' => ['id' => $user->need('uid'), 'code' => $activationCode], 'force_canonical' => true]);
$subject = sprintf($this->t('Your registration to the %s %s'),
$this->option('client.name.short', false), $this->option('service.name.full', false));
$text = sprintf($this->t("welcome to the %s %s!\r\n\r\nThank you for your registration to our service.\r\n\r\nBefore you can completely use your new user account to book spare %s online, you have to activate it by simply clicking the following link. That's all!\r\n\r\n%s"),
$this->option('client.name.full', false), $this->option('service.name.full', false), $this->option('subject.square.type.plural', false), $activationLink);
$userMailService = $serviceManager->get('User\Service\MailService');
$userMailService->send($user, $subject, $text);
}
return $this->redirect()->toRoute('user/registration-confirmation');
}
}
return array(
'registrationForm' => $registrationForm,
);
}
public function registrationConfirmationAction()
{
return array(
'activation' => $this->option('service.user.activation', false),
);
}
public function activationAction()
{
$activationUid = $this->params()->fromQuery('id');
$activationCode = urldecode($this->params()->fromQuery('code'));
if (! (is_numeric($activationUid) && $activationUid > 0)) {
throw new RuntimeException('Your activation code seems invalid. Please try again.');
}
$userManager = @$this->getServiceLocator()->get('User\Manager\UserManager');
$user = $userManager->get($activationUid, false);
if (! $user) {
throw new RuntimeException('Your activation code seems invalid. Please try again.');
}
$actualActivationCode = sha1($user->need('created'));
if ($activationCode != $actualActivationCode) {
throw new RuntimeException('Your activation code seems invalid. Please try again.');
}
$user->set('status', $user->getMeta('status_before_reactivation', 'enabled'));
$user->set('last_activity', date('Y-m-d H:i:s'));
$user->set('last_ip', $_SERVER['REMOTE_ADDR']);
$userManager->save($user);
}
public function activationResendAction()
{
if ($this->option('service.user.activation') != 'email') {
throw new RuntimeException('You cannot manually activate your account currently');
}
$serviceManager = @$this->getServiceLocator();
$formElementManager = $serviceManager->get('FormElementManager');
$activationResendForm = $formElementManager->get('User\Form\ActivationResendForm');
$activationResendMessage = null;
if ($this->getRequest()->isPost()) {
$activationResendForm->setData($this->params()->fromPost());
if ($activationResendForm->isValid()) {
$activationResendData = $activationResendForm->getData();
$userManager = $serviceManager->get('User\Manager\UserManager');
$user = current( $userManager->getBy(array('email' => $activationResendData['arf-email'])) );
if ($user) {
$mailMessage = $this->t('We have just received your request for a new user account activation email.') . "\r\n\r\n";
switch ($user->need('status')) {
case 'placeholder':
$mailMessage .= $this->t('Unfortunately, your account is considered a placeholder and thus cannot be activated.');
break;
case 'blocked':
$mailMessage .= $this->t('Unfortunately, your account is currently blocked. Please contact us for support.');
break;
case 'disabled':
/* Activation code is "created" hash */
$activationCode = urlencode( sha1($user->need('created')) );
$activationLink = $this->url()->fromRoute('user/activation', [], ['query' => ['id' => $user->need('uid'), 'code' => $activationCode], 'force_canonical' => true]);
$mailMessage .= sprintf($this->t("Before you can completely use your new user account to book spare %s online, you have to activate it by simply clicking the following link. That's all!\r\n\r\n%s"),
$this->option('subject.square.type.plural', false), $activationLink);
break;
case 'enabled':
case 'assist':
case 'admin':
$mailMessage .= $this->t('However, your account has already been activated. You can login whenever you like!');
break;
default:
$mailMessage .= $this->t('Unfortunately, your account seems somewhat unique, thus we are unsure how to treat it. Mind contacting us?');
break;
}
$userMailService = $serviceManager->get('User\Service\MailService');
$userMailService->send($user, $this->t('User account activation'), $mailMessage);
}
}
$activationResendForm->get('arf-email')->setValue('');
$activationResendMessage = sprintf('%s
(%s)
',
$this->t('All right, you should receive an email from us soon'),
$this->t('if we find a valid user account with this email address'));
}
return array(
'activationResendForm' => $activationResendForm,
'activationResendMessage' => $activationResendMessage,
);
}
public function bookingsAction()
{
$serviceManager = @$this->getServiceLocator();
$bookingManager = $serviceManager->get('Booking\Manager\BookingManager');
$bookingBillManager = $serviceManager->get('Booking\Manager\Booking\BillManager');
$reservationManager = $serviceManager->get('Booking\Manager\ReservationManager');
$squareManager = $serviceManager->get('Square\Manager\SquareManager');
$squareValidator = $serviceManager->get('Square\Service\SquareValidator');
$userSessionManager = $serviceManager->get('User\Manager\UserSessionManager');
$user = $userSessionManager->getSessionUser();
if (! $user) {
$this->redirectBack()->setOrigin('user/bookings');
return $this->redirect()->toRoute('user/login');
}
$bookings = $bookingManager->getByValidity(array('uid' => $user->need('uid')));
$reservations = $reservationManager->getByBookings($bookings, 'date DESC, time_start DESC');
$bookingBillManager->getByBookings($bookings);
return array(
'now' => new DateTime(),
'bookings' => $bookings,
'reservations' => $reservations,
'squareManager' => $squareManager,
'squareValidator' => $squareValidator,
);
}
public function billsAction()
{
$bid = $this->params()->fromRoute('bid');
$serviceManager = @$this->getServiceLocator();
$userSessionManager = $serviceManager->get('User\Manager\UserSessionManager');
$user = $userSessionManager->getSessionUser();
if (! $user) {
$this->redirectBack()->setOrigin('user/bookings/bills', ['bid' => $bid]);
return $this->redirect()->toRoute('user/login');
}
$bookingManager = $serviceManager->get('Booking\Manager\BookingManager');
$bookingBillManager = $serviceManager->get('Booking\Manager\Booking\BillManager');
$bookingStatusService = $serviceManager->get('Booking\Service\BookingStatusService');
$booking = $bookingManager->get($bid);
$bookingBillingStatus = $bookingStatusService->getStatusTitle($booking->getBillingStatus());
if ($booking->get('uid') != $user->get('uid')) {
if (! $user->can('admin.booking')) {
throw new RuntimeException('You have no permission for this');
}
}
$bills = $bookingBillManager->getBy(array('bid' => $bid), 'bbid ASC');
return array(
'booking' => $booking,
'bookingBillingStatus' => $bookingBillingStatus,
'bills' => $bills,
'user' => $user,
);
}
public function settingsAction()
{
$serviceManager = @$this->getServiceLocator();
$userManager = $serviceManager->get('User\Manager\UserManager');
$userSessionManager = $serviceManager->get('User\Manager\UserSessionManager');
$formElementManager = $serviceManager->get('FormElementManager');
$user = $userSessionManager->getSessionUser();
if (! $user) {
$this->redirectBack()->setOrigin('user/settings');
return $this->redirect()->toRoute('user/login');
}
$editParam = $this->params()->fromQuery('edit');
/* Phone form */
$editPhoneForm = $formElementManager->get('User\Form\EditPhoneForm');
if ($this->getRequest()->isPost() && $editParam == 'phone') {
$editPhoneForm->setData($this->params()->fromPost());
if ($editPhoneForm->isValid()) {
$data = $editPhoneForm->getData();
$phone = $data['epf-phone'];
$user->setMeta('phone', $phone);
$userManager->save($user);
$this->flashMessenger()->addSuccessMessage(sprintf($this->t('Your %sphone number%s has been updated'),
'', ''));
return $this->redirect()->toRoute('user/settings');
}
} else {
$editPhoneForm->get('epf-phone')->setValue($user->getMeta('phone'));
}
/* Email form */
$editEmailForm = $formElementManager->get('User\Form\EditEmailForm');
if ($this->getRequest()->isPost() && $editParam == 'email') {
$editEmailForm->setData($this->params()->fromPost());
if ($editEmailForm->isValid()) {
$data = $editEmailForm->getData();
$email = $data['eef-email1'];
$user->set('email', $email);
if ($this->option('service.user.activation') == 'email') {
$user->setMeta('status_before_reactivation',
$user->get('status'));
$user->set('status', 'disabled');
/* Activation code is "created" hash */
$activationCode = urlencode( sha1($user->need('created')) );
$activationLink = $this->url()->fromRoute('user/activation', [], ['query' => ['id' => $user->need('uid'), 'code' => $activationCode], 'force_canonical' => true]);
$subject = sprintf($this->t('New email address at %s %s'),
$this->option('client.name.short', false), $this->option('service.name.full', false));
$text = sprintf($this->t("You have just changed your account's email address to this one.\r\n\r\nBefore you can completely use your new email address to book spare %s online again, you have to activate it by simply clicking the following link. That's all!\r\n\r\n%s"),
$this->option('subject.square.type.plural', false), $activationLink);
$userMailService = $serviceManager->get('User\Service\MailService');
$userMailService->send($user, $subject, $text);
}
$userManager->save($user);
$this->flashMessenger()->addSuccessMessage(sprintf($this->t('Your %semail address%s has been updated'),
'', ''));
return $this->redirect()->toRoute('user/settings');
}
} else {
$editEmailForm->get('eef-email1')->setValue($user->get('email'));
$editEmailForm->get('eef-email2')->setValue($user->get('email'));
}
/* Notifications form */
$editNotificationsForm = $formElementManager->get('User\Form\EditNotificationsForm');
if ($this->getRequest()->isPost() && $editParam == 'notifications') {
$editNotificationsForm->setData($this->params()->fromPost());
if ($editNotificationsForm->isValid()) {
$data = $editNotificationsForm->getData();
$bookingNotifications = $data['enf-booking-notifications'];
$user->setMeta('notification.bookings', $bookingNotifications);
$userManager->save($user);
$this->flashMessenger()->addSuccessMessage(sprintf($this->t('Your %snotification settings%s have been updated'),
'', ''));
return $this->redirect()->toRoute('user/settings');
}
} else {
$editNotificationsForm->get('enf-booking-notifications')->setValue($user->getMeta('notification.bookings', 'true'));
}
/* Password form */
$editPasswordForm = $formElementManager->get('User\Form\EditPasswordForm');
if ($this->getRequest()->isPost() && $editParam == 'password') {
$editPasswordForm->setData($this->params()->fromPost());
if ($editPasswordForm->isValid()) {
$data = $editPasswordForm->getData();
$passwordCurrent = $data['epf-pw-current'];
$passwordNew = $data['epf-pw1'];
$bcrypt = new Bcrypt();
$bcrypt->setCost(6);
if ($bcrypt->verify($passwordCurrent, $user->need('pw'))) {
$user->set('pw', $bcrypt->create($passwordNew));
$userManager->save($user);
$this->flashMessenger()->addSuccessMessage(sprintf($this->t('Your %spassword%s has been updated'),
'', ''));
return $this->redirect()->toRoute('user/settings');
} else {
$editPasswordForm->get('epf-pw-current')->setMessages(array('This is not your correct password'));
}
}
}
/* Delete account form */
$deleteAccountForm = $formElementManager->get('User\Form\DeleteAccountForm');
$deleteAccountMessage = null;
if ($this->getRequest()->isPost() && $editParam == 'delete') {
$deleteAccountForm->setData($this->params()->fromPost());
if ($deleteAccountForm->isValid()) {
$data = $deleteAccountForm->getData();
$why = $data['daf-why'];
$passwordCurrent = $data['daf-pw-current'];
$bcrypt = new Bcrypt();
$bcrypt->setCost(6);
if ($bcrypt->verify($passwordCurrent, $user->need('pw'))) {
$user->set('status', 'deleted');
$user->set('last_activity', date('Y-m-d H:i:s'));
$user->set('last_ip', $_SERVER['REMOTE_ADDR']);
if ($why) {
$user->setMeta('deletion.reason', $why);
}
$userManager->save($user);
$userSessionManager->logout();
$deleteAccountMessage = sprintf($this->t('Your %suser account has been deleted%s. Good bye!'),
'', '');
} else {
$editPasswordForm->get('epf-pw-current')->setMessages(array('This is not your correct password'));
}
}
}
return array(
'user' => $user,
'editPhoneForm' => $editPhoneForm,
'editEmailForm' => $editEmailForm,
'editNotificationsForm' => $editNotificationsForm,
'editPasswordForm' => $editPasswordForm,
'deleteAccountForm' => $deleteAccountForm,
'deleteAccountMessage' => $deleteAccountMessage,
);
}
}
================================================
FILE: module/User/src/User/Controller/Plugin/Authorize.php
================================================
userSessionManager = $userSessionManager;
}
public function __invoke($privileges = null)
{
$user = $this->userSessionManager->getSessionUser();
if (! $user) {
throw new RuntimeException('You are not logged in (anymore)');
}
if ($privileges) {
if (! $user->can($privileges)) {
throw new RuntimeException('You have no permission for this');
}
}
return $user;
}
}
================================================
FILE: module/User/src/User/Controller/Plugin/AuthorizeFactory.php
================================================
getServiceLocator()->get('User\Manager\UserSessionManager'));
}
}
================================================
FILE: module/User/src/User/Controller/SessionController.php
================================================
getServiceLocator();
$userSessionManager = $serviceManager->get('User\Manager\UserSessionManager');
$user = $userSessionManager->getSessionUser();
if ($user) {
return $this->redirectBack()->toOrigin();
}
$formElementManager = $serviceManager->get('FormElementManager');
$loginForm = $formElementManager->get('User\Form\LoginForm');
$loginMessage = null;
$loginDetent = null;
if ($this->getRequest()->isPost()) {
$loginForm->setData($this->params()->fromPost());
if ($loginForm->isValid()) {
$loginData = $loginForm->getData();
$loginResult = $userSessionManager->login($loginData['lf-email'], $loginData['lf-pw']);
switch ($loginResult->getCode()) {
case ResultAlias::SUCCESS:
$user = $loginResult->getIdentity();
$this->flashMessenger()->addSuccessMessage(
sprintf($this->t('Welcome, %s'), $user->need('alias')));
return $this->redirectBack()->toOrigin();
case Result::FAILURE_TOO_MANY_TRIES:
$loginMessage = 'Due to too many login attempts, temporarily blocked until %s';
$loginDetent = $loginResult->getExtra('login_detent');
break;
case Result::FAILURE_USER_STATUS:
$user = $loginResult->getIdentity();
switch ($user->need('status')) {
case 'placeholder':
$loginMessage = 'This account is considered a placeholder and thus cannot login';
break;
case 'deleted':
$loginMessage = 'Email address and/or password invalid';
break;
case 'blocked':
$loginMessage = 'This account is currently blocked';
break;
case 'disabled':
$loginMessage = 'This account has not yet been activated';
break;
}
break;
case ResultAlias::FAILURE_IDENTITY_NOT_FOUND:
case ResultAlias::FAILURE_IDENTITY_AMBIGUOUS:
case ResultAlias::FAILURE_CREDENTIAL_INVALID:
case ResultAlias::FAILURE_UNCATEGORIZED:
case ResultAlias::FAILURE:
default:
$loginMessage = 'Email address and/or password invalid';
break;
}
} else {
if ($this->params()->fromPost('lf-email') || $this->params()->fromPost('lf-pw')) {
$loginMessage = 'Email address and/or password invalid';
}
}
$loginForm->setData( $loginForm->getData() );
}
return array(
'loginForm' => $loginForm,
'loginMessage' => $loginMessage,
'loginDetent' => $loginDetent,
);
}
public function logoutAction()
{
$serviceManager = @$this->getServiceLocator();
$userSessionManager = $serviceManager->get('User\Manager\UserSessionManager');
$user = $userSessionManager->getSessionUser();
return array(
'result' => $userSessionManager->logout(),
'user' => $user,
);
}
}
================================================
FILE: module/User/src/User/Entity/User.php
================================================
'Placeholder',
'deleted' => 'Deleted user',
'blocked' => 'Blocked user',
'disabled' => 'Waiting for activation',
'enabled' => 'Enabled user',
'assist' => 'Assist',
'admin' => 'Admin',
);
/**
* Returns the status string.
*
* @return string
*/
public function getStatus()
{
$status = $this->need('status');
return self::$statusOptions[$status] ?? 'Unknown';
}
/**
* The possible gender options.
*
* @var array
*/
public static $genderOptions = array(
'male' => 'Mr.',
'female' => 'Mrs',
'family' => 'Family',
'firm' => 'Firm',
);
/**
* Returns the gender string.
*
* @return string
*/
public function getGender($default = null)
{
$gender = $this->getMeta('gender');
if (is_null($gender)) {
return $default;
}
return self::$genderOptions[$gender] ?? 'Unknown';
}
/**
* The possible privileges.
*
* @var array
*/
public static $privileges = array(
'admin.user' => 'May manage users',
'admin.booking' => 'May manage bookings',
'admin.event' => 'May manage events',
'admin.config' => 'May change configuration',
'admin.see-menu' => 'Can see the admin menu',
'calendar.see-past' => 'Can see the past in calendar',
'calendar.see-data' => 'Can see names and data in calendar',
'calendar.create-single-bookings' => 'May create single bookings',
'calendar.cancel-single-bookings' => 'May cancel single bookings',
'calendar.delete-single-bookings' => 'May delete single bookings',
'calendar.create-subscription-bookings' => 'May create multiple bookings',
'calendar.cancel-subscription-bookings' => 'May cancel multiple bookings',
'calendar.delete-subscription-bookings' => 'May delete multiple bookings',
);
/**
* Access control for this user.
*
* @param string $privileges
* @return boolean
*/
public function can($privileges)
{
if ($this->need('status') == 'admin') {
return true;
}
if ($this->need('status') == 'assist') {
if (is_array($privileges)) {
$privileges = implode(',', $privileges);
}
if (is_string($privileges)) {
$orPrivileges = explode(',', $privileges);
$orPrivilegesMatched = 0;
foreach ($orPrivileges as $orPrivilege) {
$andPrivileges = explode('+', $orPrivilege);
$andPrivilegesMatched = 0;
foreach ($andPrivileges as $andPrivilege) {
$privilege = trim($andPrivilege);
if ($this->getMeta('allow.' . $privilege) == 'true') {
$andPrivilegesMatched++;
}
}
if ($andPrivilegesMatched == count($andPrivileges)) {
$orPrivilegesMatched++;
}
}
if ($orPrivilegesMatched >= 1) {
return true;
}
}
}
return false;
}
}
================================================
FILE: module/User/src/User/Entity/UserFactory.php
================================================
setName('arf');
$this->add(array(
'name' => 'arf-email',
'type' => 'Text',
'attributes' => array(
'id' => 'arf-email',
'class' => 'autofocus',
'style' => 'width: 250px;',
),
'options' => array(
'label' => 'Email address',
'label_attributes' => array(
'class' => 'symbolic symbolic-email',
),
),
));
$this->add(array(
'name' => 'arf-submit',
'type' => 'Submit',
'attributes' => array(
'value' => 'Request activation mail',
'class' => 'default-button',
'style' => 'width: 200px;',
),
));
/* Input filters */
$factory = new Factory();
$this->setInputFilter($factory->createInputFilter(array(
'arf-email' => array(
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'break_chain_on_failure' => true,
),
array(
'name' => 'EmailAddress',
),
),
),
)));
}
}
================================================
FILE: module/User/src/User/Form/DeleteAccountForm.php
================================================
setName('daf');
$this->add(array(
'name' => 'daf-why',
'type' => 'Text',
'attributes' => array(
'id' => 'daf-why',
'style' => 'width: 640px;',
),
'options' => array(
'notes' => 'Were you not happy with our service? Please tell us why you leave. Thank you!',
),
));
$this->add(array(
'name' => 'daf-pw-current',
'type' => 'Password',
'attributes' => array(
'id' => 'daf-pw-current',
'style' => 'width: 235px;',
),
'options' => array(
'notes' => 'Your current password',
),
));
$this->add(array(
'name' => 'daf-submit',
'type' => 'Submit',
'attributes' => array(
'value' => 'Delete account',
'class' => 'default-button',
),
));
/* Input filters */
$factory = new Factory();
$this->setInputFilter($factory->createInputFilter(array(
'daf-why' => array(
'required' => false,
'filters' => array(
array('name' => 'StringTrim'),
array('name' => 'StripTags'),
),
),
'daf-pw-current' => array(
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'message' => 'Please type your password here',
),
'break_chain_on_failure' => true,
),
),
),
)));
}
}
================================================
FILE: module/User/src/User/Form/EditEmailForm.php
================================================
userManager = $userManager;
}
public function init()
{
$this->setName('eef');
$this->add(array(
'name' => 'eef-email1',
'type' => 'Text',
'attributes' => array(
'id' => 'eef-email1',
'style' => 'width: 235px;',
),
'options' => array(
'notes' => 'Please provide your email address',
),
));
$this->add(array(
'name' => 'eef-email2',
'type' => 'Text',
'attributes' => array(
'id' => 'eef-email2',
'style' => 'width: 235px;',
),
'options' => array(
'notes' => 'Please type your email address again to prevent typing errors',
),
));
$this->add(array(
'name' => 'eef-submit',
'type' => 'Submit',
'attributes' => array(
'value' => 'Update email address',
'class' => 'default-button',
),
));
/* Input filters */
$userManager = $this->userManager;
$factory = new Factory();
$this->setInputFilter($factory->createInputFilter(array(
'eef-email1' => array(
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'message' => 'Please type your email address here',
),
'break_chain_on_failure' => true,
),
array(
'name' => 'EmailAddress',
'options' => array(
'useMxCheck' => true,
'message' => 'Please type your correct email address here',
'messages' => array(
'emailAddressInvalidMxRecord' => 'We could not verify your email provider',
),
),
'break_chain_on_failure' => true,
),
array(
'name' => 'Callback',
'options' => array(
'callback' => function($value) {
$blacklist = getcwd() . '/data/res/blacklist-emails.txt';
if (is_readable($blacklist)) {
$blacklistContent = file_get_contents($blacklist);
$blacklistDomains = explode("\r\n", $blacklistContent);
foreach ($blacklistDomains as $blacklistDomain) {
$blacklistPattern = str_replace('.', '\.', $blacklistDomain);
if (preg_match('/' . $blacklistPattern . '$/', $value)) {
return false;
}
}
}
return true;
},
'message' => 'Trash mail addresses are currently blocked - sorry',
),
'break_chain_on_failure' => true,
),
array(
'name' => 'Callback',
'options' => array(
'callback' => function($value) use ($userManager) {
if ($userManager->getBy(array('email' => $value))) {
return false;
} else {
return true;
}
},
'message' => 'This email address has already been registered',
),
),
),
),
'eef-email2' => array(
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'message' => 'Please type your email address here',
),
'break_chain_on_failure' => true,
),
array(
'name' => 'Identical',
'options' => array(
'token' => 'eef-email1',
'message' => array(
'Both email addresses must be identical',
),
),
),
),
),
)));
}
}
================================================
FILE: module/User/src/User/Form/EditEmailFormFactory.php
================================================
getServiceLocator()->get('User\Manager\UserManager'));
}
}
================================================
FILE: module/User/src/User/Form/EditNotificationsForm.php
================================================
setName('enf');
$this->add(array(
'name' => 'enf-booking-notifications',
'type' => 'Checkbox',
'attributes' => array(
'id' => 'enf-booking-notifications',
),
'options' => array(
'label' => 'Notify on bookings and cancellations',
'notes' => 'We can send you confirmations per email',
'checked_value' => 'true',
'unchecked_value' => 'false',
),
));
$this->add(array(
'name' => 'enf-submit',
'type' => 'Submit',
'attributes' => array(
'value' => 'Update settings',
'class' => 'default-button',
),
));
}
}
================================================
FILE: module/User/src/User/Form/EditPasswordForm.php
================================================
setName('epf');
$this->add(array(
'name' => 'epf-pw-current',
'type' => 'Password',
'attributes' => array(
'id' => 'epf-pw-current',
'style' => 'width: 235px;',
),
'options' => array(
'notes' => 'Your current password',
),
));
$this->add(array(
'name' => 'epf-pw1',
'type' => 'Password',
'attributes' => array(
'id' => 'epf-pw1',
'style' => 'width: 235px;',
),
'options' => array(
'notes' => 'Your new password',
),
));
$this->add(array(
'name' => 'epf-pw2',
'type' => 'Password',
'attributes' => array(
'id' => 'epf-pw2',
'style' => 'width: 235px;',
),
'options' => array(
'notes' => 'Please type your new password again to prevent typing errors',
),
));
$this->add(array(
'name' => 'epf-submit',
'type' => 'Submit',
'attributes' => array(
'value' => 'Update password',
'class' => 'default-button',
),
));
/* Input filters */
$factory = new Factory();
$this->setInputFilter($factory->createInputFilter(array(
'epf-pw-current' => array(
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'message' => 'Please type your password here',
),
'break_chain_on_failure' => true,
),
),
),
'epf-pw1' => array(
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'message' => 'Please type a new password here',
),
'break_chain_on_failure' => true,
),
array(
'name' => 'StringLength',
'options' => array(
'min' => 4,
'message' => 'Your new password should be at least %min% characters long',
),
),
),
),
'epf-pw2' => array(
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'message' => 'Please type a new password here',
),
'break_chain_on_failure' => true,
),
array(
'name' => 'Identical',
'options' => array(
'token' => 'epf-pw1',
'message' => 'Both passwords must be identical',
),
),
),
),
)));
}
}
================================================
FILE: module/User/src/User/Form/EditPhoneForm.php
================================================
setName('epf');
$this->add(array(
'name' => 'epf-phone',
'type' => 'Text',
'attributes' => array(
'id' => 'epf-phone',
'style' => 'width: 235px;',
),
'options' => array(
'notes' => 'We only use this to inform you about changes to your bookings',
),
));
$this->add(array(
'name' => 'epf-submit',
'type' => 'Submit',
'attributes' => array(
'value' => 'Update phone number',
'class' => 'default-button',
),
));
/* Input filters */
$factory = new Factory();
$this->setInputFilter($factory->createInputFilter(array(
'epf-phone' => array(
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'message' => 'Please type your phone number here',
),
'break_chain_on_failure' => true,
),
array(
'name' => 'StringLength',
'options' => array(
'min' => 3,
'message' => 'This phone number is somewhat short ...',
),
),
array(
'name' => 'Regex',
'options' => array(
'pattern' => '/^([ \+\/\(\)\-0-9])+$/u',
'message' => 'This phone number contains invalid characters - sorry',
),
),
),
),
)));
}
}
================================================
FILE: module/User/src/User/Form/LoginForm.php
================================================
setName('lf');
$this->add(array(
'name' => 'lf-email',
'type' => 'Text',
'attributes' => array(
'id' => 'lf-email',
'class' => 'autofocus',
'style' => 'width: 250px;',
),
'options' => array(
'label' => 'Email address',
'label_attributes' => array(
'class' => 'symbolic symbolic-email',
),
),
));
$this->add(array(
'name' => 'lf-pw',
'type' => 'Password',
'attributes' => array(
'id' => 'lf-pw',
'style' => 'width: 250px;',
),
'options' => array(
'label' => 'Password',
'label_attributes' => array(
'class' => 'symbolic symbolic-pw',
),
),
));
$this->add(array(
'name' => 'lf-submit',
'type' => 'Submit',
'attributes' => array(
'value' => 'Login',
'class' => 'default-button',
'style' => 'width: 175px;',
),
));
/* Input filters */
$factory = new Factory();
$this->setInputFilter($factory->createInputFilter(array(
'lf-email' => array(
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'break_chain_on_failure' => true,
),
array(
'name' => 'EmailAddress',
),
),
),
'lf-submit' => array(
'fallback_value' => 'Login',
),
)));
}
}
================================================
FILE: module/User/src/User/Form/PasswordForm.php
================================================
setName('pf');
$this->add(array(
'name' => 'pf-email',
'type' => 'Text',
'attributes' => array(
'id' => 'pf-email',
'class' => 'autofocus',
'style' => 'width: 250px;',
),
'options' => array(
'label' => 'Email address',
'label_attributes' => array(
'class' => 'symbolic symbolic-email',
'label_attributes' => array(
'class' => 'symbolic symbolic-email',
),
),
),
));
$this->add(array(
'name' => 'pf-submit',
'type' => 'Submit',
'attributes' => array(
'value' => 'Change password',
'class' => 'default-button',
'style' => 'width: 175px;',
),
));
/* Input filters */
$factory = new Factory();
$this->setInputFilter($factory->createInputFilter(array(
'pf-email' => array(
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'break_chain_on_failure' => true,
),
array(
'name' => 'EmailAddress',
),
),
),
)));
}
}
================================================
FILE: module/User/src/User/Form/PasswordResetForm.php
================================================
setName('prf');
$this->add(array(
'name' => 'prf-pw1',
'type' => 'Password',
'attributes' => array(
'id' => 'prf-pw1',
'class' => 'autofocus',
'style' => 'width: 250px;',
),
'options' => array(
'label' => 'New password',
'label_attributes' => array(
'class' => 'symbolic symbolic-pw',
),
'notes' => 'Your password will be safely encrypted',
),
));
$this->add(array(
'name' => 'prf-pw2',
'type' => 'Password',
'attributes' => array(
'id' => 'prf-pw2',
'style' => 'width: 250px;',
),
'options' => array(
'label' => ' ',
'notes' => 'Please type your password again',
),
));
$this->add(array(
'name' => 'prf-submit',
'type' => 'Submit',
'attributes' => array(
'value' => 'Change password',
'class' => 'default-button',
'style' => 'width: 175px;',
),
));
/* Input filters */
$factory = new Factory();
$this->setInputFilter($factory->createInputFilter(array(
'prf-pw1' => array(
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'message' => 'Please type your password',
),
'break_chain_on_failure' => true,
),
array(
'name' => 'StringLength',
'options' => array(
'min' => 4,
'message' => 'Your new password should be at least %min% characters long',
),
),
),
),
'prf-pw2' => array(
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'message' => 'Please type your password here',
),
'break_chain_on_failure' => true,
),
array(
'name' => 'Identical',
'options' => array(
'token' => 'prf-pw1',
'message' => 'Both passwords must be identical',
),
),
),
),
)));
}
}
================================================
FILE: module/User/src/User/Form/RegistrationForm.php
================================================
optionManager = $optionManager;
$this->userManager = $userManager;
}
public function init()
{
$this->setName('rf');
/* Credentials */
$this->add(array(
'name' => 'rf-email1',
'type' => 'Text',
'attributes' => array(
'id' => 'rf-email1',
'class' => 'autofocus',
'style' => 'width: 250px;',
),
'options' => array(
'label' => 'Email address',
'label_attributes' => array(
'class' => 'symbolic symbolic-email',
),
'notes' => 'Please provide your email address',
),
));
$this->add(array(
'name' => 'rf-email2',
'type' => 'Text',
'attributes' => array(
'id' => 'rf-email2',
'style' => 'width: 250px;',
),
'options' => array(
'label' => ' ',
'notes' => 'Please type your email address again to prevent typing errors',
),
));
$this->add(array(
'name' => 'rf-pw1',
'type' => 'Password',
'attributes' => array(
'id' => 'rf-pw1',
'style' => 'width: 250px;',
),
'options' => array(
'label' => 'Password',
'label_attributes' => array(
'class' => 'symbolic symbolic-pw',
),
'notes' => 'Your password will be safely encrypted',
),
));
$this->add(array(
'name' => 'rf-pw2',
'type' => 'Password',
'attributes' => array(
'id' => 'rf-pw2',
'style' => 'width: 250px;',
),
'options' => array(
'label' => ' ',
'notes' => 'Please type your password again to prevent typing errors',
),
));
/* Personal data */
$this->add(array(
'name' => 'rf-gender',
'type' => 'Select',
'attributes' => array(
'id' => 'rf-gender',
),
'options' => array(
'label' => 'Salutation',
'value_options' => User::$genderOptions,
),
));
$this->add(array(
'name' => 'rf-firstname',
'type' => 'Text',
'attributes' => array(
'id' => 'rf-firstname',
'style' => 'width: 116px;',
),
'options' => array(
'label' => 'First & Last name',
),
));
$this->add(array(
'name' => 'rf-lastname',
'type' => 'Text',
'attributes' => array(
'id' => 'rf-lastname',
'style' => 'width: 116px;',
),
'options' => array(
'label' => 'Last name',
),
));
$this->add(array(
'name' => 'rf-street',
'type' => 'Text',
'attributes' => array(
'id' => 'rf-street',
'style' => 'width: 182px;',
),
'options' => array(
'label' => 'Street & Number',
),
));
$this->add(array(
'name' => 'rf-number',
'type' => 'Text',
'attributes' => array(
'id' => 'rf-number',
'style' => 'width: 50px;',
),
'options' => array(
'label' => 'Street number',
),
));
$this->add(array(
'name' => 'rf-zip',
'type' => 'Text',
'attributes' => array(
'id' => 'rf-zip',
'style' => 'width: 116px;',
),
'options' => array(
'label' => 'Postal code & City',
),
));
$this->add(array(
'name' => 'rf-city',
'type' => 'Text',
'attributes' => array(
'id' => 'rf-city',
'style' => 'width: 116px;',
),
'options' => array(
'label' => 'City',
),
));
$this->add(array(
'name' => 'rf-phone',
'type' => 'Text',
'attributes' => array(
'id' => 'rf-phone',
'style' => 'width: 250px;',
),
'options' => array(
'label' => 'Phone number',
'notes' => 'We only use this to inform you about changes to your bookings',
),
));
/*
* Optional birthdate input not allowed anymore by EU GDPR
*
$this->add(array(
'name' => 'rf-birthdate',
'type' => 'Text',
'attributes' => array(
'id' => 'rf-birthdate',
'style' => 'width: 116px;',
),
'options' => array(
'label' => 'Birthday',
'notes' => 'We need this, because ...',
),
));
*/
/* Add business terms and privacy policy if configured */
$termsFile = $this->optionManager->get('service.user.registration.terms.file');
if ($termsFile) {
$this->add(array(
'name' => 'rf-terms',
'type' => 'Checkbox',
'attributes' => array(
'id' => 'rf-terms',
),
'options' => array(
'label' => 'I agree to %s',
'checked_value' => 'true',
'unchecked_value' => 'false',
),
));
}
$privacyFile = $this->optionManager->get('service.user.registration.privacy.file');
if ($privacyFile) {
$this->add(array(
'name' => 'rf-privacy',
'type' => 'Checkbox',
'attributes' => array(
'id' => 'rf-privacy',
),
'options' => array(
'label' => 'I agree to %s',
'checked_value' => 'true',
'unchecked_value' => 'false',
),
));
}
/* Add fake nickname to fool spam bots */
$this->add(array(
'name' => 'rf-nickname',
'type' => 'Text',
'attributes' => array(
'style' => 'display: none;',
),
));
/* Add weak CSRF protection */
$time = time();
$bcrypt = new Bcrypt();
$bcrypt->setCost(6);
$bcrypt->setSalt(str_pad(php_uname(), 16, '!'));
$this->add(array(
'name' => 'rf-csrf',
'type' => 'Hidden',
'attributes' => array(
'value' => $time . $bcrypt->create($time),
),
));
$this->add(array(
'name' => 'rf-submit',
'type' => 'Submit',
'attributes' => array(
'value' => 'Complete registration',
'class' => 'default-button',
'style' => 'width: 250px;',
),
));
/* Input filters */
$userManager = $this->userManager;
$factory = new Factory();
$this->setInputFilter($factory->createInputFilter(array(
'rf-email1' => array(
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'message' => 'Please type your email address here',
),
'break_chain_on_failure' => true,
),
array(
'name' => 'EmailAddress',
'options' => array(
'useMxCheck' => true,
'message' => 'Please type your correct email address here',
'messages' => array(
'emailAddressInvalidMxRecord' => 'We could not verify your email provider',
),
),
'break_chain_on_failure' => true,
),
array(
'name' => 'Callback',
'options' => array(
'callback' => function($value) {
$blacklist = getcwd() . '/data/res/blacklist-emails.txt';
if (is_readable($blacklist)) {
$blacklistContent = file_get_contents($blacklist);
$blacklistDomains = explode("\r\n", $blacklistContent);
foreach ($blacklistDomains as $blacklistDomain) {
$blacklistPattern = str_replace('.', '\.', $blacklistDomain);
if (preg_match('/' . $blacklistPattern . '$/', $value)) {
return false;
}
}
}
return true;
},
'message' => 'Trash mail addresses are currently blocked - sorry',
),
'break_chain_on_failure' => true,
),
array(
'name' => 'Callback',
'options' => array(
'callback' => function($value) use ($userManager) {
if ($userManager->getBy(array('email' => $value))) {
return false;
} else {
return true;
}
},
'message' => 'This email address has already been registered',
),
),
),
),
'rf-email2' => array(
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'message' => 'Please type your email address here',
),
'break_chain_on_failure' => true,
),
array(
'name' => 'Identical',
'options' => array(
'token' => 'rf-email1',
'message' => array(
'Both email addresses must be identical',
),
),
),
),
),
'rf-pw1' => array(
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'message' => 'Please type your password here',
),
'break_chain_on_failure' => true,
),
array(
'name' => 'StringLength',
'options' => array(
'min' => 4,
'message' => 'Your password should be at least %min% characters long',
),
),
),
),
'rf-pw2' => array(
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'message' => 'Please type your password here',
),
'break_chain_on_failure' => true,
),
array(
'name' => 'Identical',
'options' => array(
'token' => 'rf-pw1',
'message' => 'Both passwords must be identical',
),
),
),
),
'rf-firstname' => array(
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'message' => 'Please type your name here',
),
'break_chain_on_failure' => true,
),
array(
'name' => 'StringLength',
'options' => array(
'min' => 3,
'message' => 'Your name is somewhat short ...',
),
),
array(
'name' => 'Regex',
'options' => array(
'pattern' => '/^([ \&\'\(\)\+\,\-\.0-9\x{00c0}-\x{01ff}a-zA-Z])+$/u',
'message' => 'Your name contains invalid characters - sorry',
),
),
),
),
'rf-lastname' => array(
'required' => false,
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'min' => 3,
'message' => 'Your last name is somewhat short ...',
),
),
array(
'name' => 'Regex',
'options' => array(
'pattern' => '/^([ \'\+\-\x{00c0}-\x{01ff}a-zA-Z])+$/u',
'message' => 'Your last name contains invalid characters - sorry',
),
),
),
),
'rf-street' => array(
'filters' => array(
array('name' => 'StringTrim'),
array('name' => 'Callback', 'options' => array('callback' => function($name) { return ucfirst($name); })),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'message' => 'Please type your street name here',
),
'break_chain_on_failure' => true,
),
array(
'name' => 'StringLength',
'options' => array(
'min' => 2,
'message' => 'This street name is somewhat short ...',
),
),
array(
'name' => 'Regex',
'options' => array(
'pattern' => '/^([ \.\'\-\x{00c0}-\x{01ff}a-zA-Z0-9])+$/u',
'message' => 'This street name contains invalid characters - sorry',
),
),
),
),
'rf-number' => array(
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'message' => 'Please type your street number here',
),
'break_chain_on_failure' => true,
),
array(
'name' => 'Regex',
'options' => array(
'pattern' => '/^([0-9a-zA-Z\.\-\/])+$/u',
'message' => 'This street number contains invalid characters - sorry',
),
),
),
),
'rf-zip' => array(
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'message' => 'Please type your postal code here',
),
'break_chain_on_failure' => true,
),
array(
'name' => 'Regex',
'options' => array(
'pattern' => '/^[0-9]{4,6}$/',
'message' => 'Please provide a correct postal code',
),
),
),
),
'rf-city' => array(
'filters' => array(
array('name' => 'StringTrim'),
array('name' => 'Callback', 'options' => array('callback' => function($name) { return ucfirst($name); })),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'message' => 'Please type your city here',
),
'break_chain_on_failure' => true,
),
array(
'name' => 'StringLength',
'options' => array(
'min' => 3,
'message' => 'This city name is somewhat short ...',
),
),
array(
'name' => 'Regex',
'options' => array(
'pattern' => '/^([ \&\'\(\)\.\-\x{00c0}-\x{01ff}a-zA-Z])+$/u',
'message' => 'This city name contains invalid characters - sorry',
),
),
),
),
'rf-phone' => array(
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'message' => 'Please type your phone number here',
),
'break_chain_on_failure' => true,
),
array(
'name' => 'StringLength',
'options' => array(
'min' => 3,
'message' => 'This phone number is somewhat short ...',
),
),
array(
'name' => 'Regex',
'options' => array(
'pattern' => '/^([ \+\/\(\)\-0-9])+$/u',
'message' => 'This phone number contains invalid characters - sorry',
),
),
),
),
/*
'rf-birthdate' => array(
'required' => true,
'filters' => array(
array('name' => 'StringTrim'),
),
),
*/
'rf-terms' => array(
'required' => false,
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'message' => 'Please accept this',
),
'break_chain_on_failure' => true,
),
array(
'name' => 'Callback',
'options' => array(
'callback' => function($value) {
return $value === 'true';
},
'message' => 'Please agree to this',
),
'break_chain_on_failure' => true,
),
),
),
'rf-privacy' => array(
'required' => false,
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'message' => 'Please accept this',
),
'break_chain_on_failure' => true,
),
array(
'name' => 'Callback',
'options' => array(
'callback' => function($value) {
return $value === 'true';
},
'message' => 'Please agree to this',
),
'break_chain_on_failure' => true,
),
),
),
'rf-nickname' => array(
'required' => false,
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'max' => 0,
'message' => 'Please leave this field empty',
),
),
),
),
'rf-csrf' => array(
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'message' => 'Please register over our website only',
),
'break_chain_on_failure' => true,
),
array(
'name' => 'Callback',
'options' => array(
'callback' => function($value) use ($bcrypt) {
$time = time();
$formTime = substr($value, 0, strlen($time));
$formTimeHash = substr($value, strlen($time));
if ($formTimeHash != $bcrypt->create($formTime)) {
return false;
}
// Allow form submission after five seconds and until one hour
if (time() - $formTime < 5 || time() - $formTime > 60 * 60) {
return false;
} else {
return true;
}
},
'message' => 'You were too quick for our system! Please wait some seconds and try again. Thank you!',
),
),
),
),
)));
}
}
================================================
FILE: module/User/src/User/Form/RegistrationFormFactory.php
================================================
getServiceLocator()->get('Base\Manager\OptionManager'),
$sm->getServiceLocator()->get('User\Manager\UserManager'));
}
}
================================================
FILE: module/User/src/User/Manager/UserManager.php
================================================
userTable = $userTable;
$this->userMetaTable = $userMetaTable;
}
/**
* Creates a new user.
*
* @param string $alias
* @param string $status
* @param string $email
* @param string $pw
* @param array $meta
* @return User
*/
public function create($alias, $status = 'placeholder', $email = null, $pw = null, array $meta = array())
{
if (! (is_string($alias) && strlen($alias) >= 3)) {
throw new InvalidArgumentException('User name too short');
}
$bcrypt = new Bcrypt();
$bcrypt->setCost(6);
$user = new User(array(
'alias' => $alias,
'status' => $status,
'email' => $email,
'pw' => $bcrypt->create($pw),
), $meta);
$this->save($user);
$this->getEventManager()->trigger('create', $user);
return $user;
}
/**
* Saves (updates or creates) a user.
*
* @param User $user
* @throws Exception
* @return User
*/
public function save(User $user)
{
$connection = $this->userTable->getAdapter()->getDriver()->getConnection();
if (! $connection->inTransaction()) {
$connection->beginTransaction();
$transaction = true;
} else {
$transaction = false;
}
try {
if ($user->get('uid')) {
/* Update existing user */
/* Determine updated properties */
$updates = array();
foreach ($user->need('updatedProperties') as $property) {
$updates[$property] = $user->get($property);
}
if ($updates) {
$this->userTable->update($updates, array('uid' => $user->get('uid')));
}
/* Determine new meta properties */
foreach ($user->need('insertedMetaProperties') as $metaProperty) {
$this->userMetaTable->insert(array(
'uid' => $user->get('uid'),
'key' => $metaProperty,
'value' => $user->needMeta($metaProperty),
));
}
/* Determine updated meta properties */
foreach ($user->need('updatedMetaProperties') as $metaProperty) {
$this->userMetaTable->update(array(
'value' => $user->needMeta($metaProperty),
), array('uid' => $user->get('uid'), 'key' => $metaProperty));
}
/* Determine removed meta properties */
foreach ($user->need('removedMetaProperties') as $metaProperty) {
$this->userMetaTable->delete(array('uid' => $user->get('uid'), 'key' => $metaProperty));
}
$user->reset();
$this->getEventManager()->trigger('save.update', $user);
} else {
/* Insert user */
$created = date('Y-m-d H:i:s');
if ($user->getExtra('nuid')) {
$uid = $user->getExtra('nuid');
} else {
$uid = null;
}
$this->userTable->insert(array(
'uid' => $uid,
'alias' => $user->need('alias'),
'status' => $user->need('status'),
'email' => $user->get('email'),
'pw' => $user->get('pw'),
'login_attempts' => $user->get('login_attempts'),
'login_detent' => $user->get('login_detent'),
'last_activity' => $user->get('last_activity'),
'last_ip' => $user->get('last_ip'),
'created' => $user->get('created', $created),
));
$uid = $this->userTable->getLastInsertValue();
if (! (is_numeric($uid) && $uid > 0)) {
throw new RuntimeException('Failed to save user');
}
foreach ($user->need('meta') as $key => $value) {
$this->userMetaTable->insert(array(
'uid' => $uid,
'key' => $key,
'value' => $value,
));
if (! $this->userMetaTable->getLastInsertValue()) {
throw new RuntimeException( sprintf('Failed to save user meta key "%s"', $key) );
}
}
$user->add('uid', $uid);
if (! $user->get('created')) {
$user->add('created', $created);
}
$this->getEventManager()->trigger('save.insert', $user);
}
if ($transaction) {
$connection->commit();
$transaction = false;
}
$this->getEventManager()->trigger('save', $user);
return $user;
} catch (Exception $e) {
if ($transaction) {
$connection->rollback();
}
throw $e;
}
}
/**
* Gets the user by primary id.
*
* @param int $uid
* @param boolean $strict
* @return User
* @throws RuntimeException
*/
public function get($uid, $strict = true)
{
$users = $this->getBy(array('uid' => $uid));
if (empty($users)) {
if ($strict) {
throw new RuntimeException('This user does not exist');
}
return null;
} else {
return $this->buffer[$uid] = current($users);
}
}
/**
* Gets all users that match the passed conditions.
*
* @param mixed $where Any valid where conditions, but usually an array with key/value pairs.
* @param string $order
* @param int $limit
* @param int $offset
* @param boolean $loadMeta
* @return array
*/
public function getBy($where, $order = null, $limit = null, $offset = null, $loadMeta = true)
{
$select = $this->userTable->getSql()->select();
if ($where) {
$select->where($where);
}
if ($order) {
$select->order($order);
}
if ($limit) {
$select->limit($limit);
if ($offset) {
$select->offset($offset);
}
}
$resultSet = $this->userTable->selectWith($select);
$users = UserFactory::fromResultSet($resultSet);
if (! ($users && $loadMeta)) {
return $users;
}
/* Load user meta data */
$uids = array();
foreach ($users as $user) {
$uids[] = $user->need('uid');
}
reset($users);
$metaSelect = $this->userMetaTable->getSql()->select();
$metaSelect->where(new In('uid', $uids));
$metaResultSet = $this->userMetaTable->selectWith($metaSelect);
return UserFactory::fromMetaResultSet($users, $metaResultSet);
}
/**
* Gets users by bookings.
*
* Users will be added to the bookings under the extra key 'user'.
*
* @param array $bookings
* @return array
* @throws InvalidArgumentException
*/
public function getByBookings(array $bookings)
{
if (empty($bookings)) {
return array();
}
$uids = array();
foreach ($bookings as $booking) {
if (! ($booking instanceof Booking)) {
throw new InvalidArgumentException('Booking objects required to load from');
}
$uid = $booking->need('uid');
if (! in_array($uid, $uids)) {
$uids[] = $uid;
}
}
$users = $this->getBy(new In(UserTable::NAME . '.uid', $uids));
foreach ($bookings as $booking) {
$booking->setExtra('user', $users[$booking->need('uid')]);
}
return $users;
}
public function getByPhoneNumber($number)
{
$resultSet = $this->userMetaTable->select(['key' => 'phone', 'value' => $number]);
foreach ($resultSet as $resultRecord) {
return $this->get($resultRecord->uid);
}
return null;
}
/**
* Gets all users.
*
* @param string $order
* @param int $limit
* @param int $offset
* @param boolean $loadMeta
* @return array
*/
public function getAll($order = null, $limit = null, $offset = null, $loadMeta = true)
{
return $this->getBy(null, $order, $limit, $offset, $loadMeta);
}
/**
* Interprets the input to return matching users.
*
* @param int|string $input Any input for interpretation;
* numeric or at least three chars long
* @param int $limit Maximum number of users to return
* @param boolean $loadMeta Whether to also load meta data
* @param array $where Additional where clauses
* @return array An array of matching user objects;
* empty if invalid input or no results
* @throws InvalidArgumentException
*/
public function interpret($input, $limit = null, $loadMeta = false, array $where = array())
{
if (! (is_numeric($input) || is_string($input))) {
throw new InvalidArgumentException('User interpretation requires either numeric or string input');
}
if (! is_numeric($input) && is_string($input) && strlen($input) < 3) {
return array();
}
if (is_numeric($input)) {
$user = $this->get($input, false);
if ($user) {
return array($user->need('uid') => $user);
} else {
return array();
}
} else {
if (empty($where)) {
$where = array(
new NotIn('status', array('deleted', 'disabled')),
);
}
return $this->getBy(array_merge(array(new Like('alias', '%' . $input . '%')), $where), 'alias ASC', $limit, null, $loadMeta);
}
}
/**
* Deletes one user and all respective meta properties (through database foreign keys).
*
* @param int|User $user
* @return int
* @throws InvalidArgumentException
*/
public function delete($user)
{
if ($user instanceof User) {
$uid = $user->need('uid');
} else {
$uid = $user;
}
if (! (is_numeric($uid) && $uid > 0)) {
throw new InvalidArgumentException('User id must be numeric');
}
$user = $this->get($uid);
$deletion = $this->userTable->delete(array('uid' => $uid));
$this->getEventManager()->trigger('delete', $user);
return $deletion;
}
}
================================================
FILE: module/User/src/User/Manager/UserManagerFactory.php
================================================
get('User\Table\UserTable'),
$sm->get('User\Table\UserMetaTable'));
}
}
================================================
FILE: module/User/src/User/Manager/UserSessionManager.php
================================================
configManager = $configManager;
$this->userManager = $userManager;
$this->sessionManager = $sessionManager;
/* Prepare session validators */
$sessionManager->getValidatorChain()->attach('session.validate', array(new HttpUserAgent(), 'isValid'));
$sessionManager->getValidatorChain()->attach('session.validate', array(new RemoteAddr(), 'isValid'));
}
/**
* Sets the user session container.
*
* @param Container $sessionContainer
*/
public function setSessionContainer(Container $sessionContainer)
{
$this->sessionContainer = $sessionContainer;
}
/**
* Gets the user session container.
*
* @return Container
*/
public function getSessionContainer($namespace = 'UserSession')
{
if (! $this->sessionContainer) {
$this->setSessionContainer(new Container($namespace));
}
return $this->sessionContainer;
}
/**
* Gets the current session user.
*
* @return User|null
*/
public function getSessionUser()
{
if ($this->user) {
return $this->user;
} else {
$sessionName = $this->configManager->need('session_config.name');
if (isset($_COOKIE[$sessionName])) {
$container = $this->getSessionContainer();
if (isset($container->uid) && is_numeric($container->uid) && $container->uid > 0) {
return $this->user = $this->userManager->get($container->uid, false);
}
}
}
return null;
}
/**
* Creates the session for the user with the passed credentials.
*
* @param string $email
* @param string $pw
* @return Result
*/
public function login($email, $pw)
{
$users = $this->userManager->getBy(array(
'email' => $email,
));
if (count($users) == 0) {
return new Result(ResultAlias::FAILURE_IDENTITY_NOT_FOUND, $email);
}
if (count($users) >= 2) {
return new Result(ResultAlias::FAILURE_IDENTITY_AMBIGUOUS, $email);
}
$user = current($users);
/* Check for current login detent */
$currentDateTime = new DateTime();
if ($user->get('login_detent')) {
$loginDetent = new DateTime($user->get('login_detent'));
if ($loginDetent > $currentDateTime) {
$result = new Result(Result::FAILURE_TOO_MANY_TRIES, $user);
$result->setExtra('login_detent', $loginDetent);
return $result;
}
}
$bcrypt = new Bcrypt();
$bcrypt->setCost(6);
/* If legacy password is detected, use it for login and then delete it */
if ($user->getMeta('legacy-pw')) {
$legacyPw = $user->getMeta('legacy-pw');
if ($legacyPw == md5($pw)) {
$user->set('pw', $bcrypt->create($pw));
$user->setMeta('legacy-pw', null);
}
}
/* Check original credentials */
if ($bcrypt->verify($pw, $user->need('pw'))) {
/* Check user status */
switch ($user->need('status')) {
case 'placeholder':
case 'deleted':
case 'blocked':
case 'disabled':
return new Result(Result::FAILURE_USER_STATUS, $user);
}
/* Create the session */
$container = $this->getSessionContainer();
$container->uid = $user->need('uid');
$container->status = $user->need('status');
/* Update last activity and ip */
$user->set('login_attempts', null);
$user->set('login_detent', null);
$user->set('last_activity', date('Y-m-d H:i:s'));
$user->set('last_ip', $_SERVER['REMOTE_ADDR']);
$this->userManager->save($user);
/* Inform anyone interested in this */
$this->getEventManager()->trigger('login', $user);
return new Result(ResultAlias::SUCCESS, $user);
}
/* Invalid password passed, prepare detent */
$loginAttempts = $user->get('login_attempts');
if (! $loginAttempts) {
$loginAttempts = 0;
}
$loginAttempts++;
if ($loginAttempts >= $this->attemptsAllowed) {
$loginAttempts = null;
$loginDetent = clone $currentDateTime;
$loginDetent->modify( sprintf('+%u sec', $this->detentDuration) );
} else {
$loginDetent = null;
}
$user->set('login_attempts', $loginAttempts);
$user->set('login_detent', $loginDetent?->format('Y-m-d H:i:s'));
$this->userManager->save($user);
return new Result(ResultAlias::FAILURE_CREDENTIAL_INVALID, $user);
}
/**
* Deletes the session from the current session user.
*
* @return boolean
*/
public function logout()
{
$user = $this->getSessionUser();
if (! $user) {
return false;
}
/* Update last activity and ip */
$user->set('last_activity', date('Y-m-d H:i:s'));
$user->set('last_ip', $_SERVER['REMOTE_ADDR']);
$this->userManager->save($user);
/* Bye ... */
$container = $this->getSessionContainer();
$container->uid = null;
$container->status = null;
$this->sessionManager->destroy();
$this->user = null;
/* Oh wait, inform anyone interested in this */
$this->getEventManager()->trigger('logout', $user);
return true;
}
}
================================================
FILE: module/User/src/User/Manager/UserSessionManagerFactory.php
================================================
get('Base\Manager\ConfigManager'),
$sm->get('User\Manager\UserManager'),
$sm->get('Zend\Session\SessionManager'));
}
}
================================================
FILE: module/User/src/User/Service/MailService.php
================================================
baseMailService = $baseMailService;
$this->configManager = $configManager;
$this->optionManager = $optionManager;
}
public function send(User $recipient, $subject, $text, array $attachments = array())
{
$fromAddress = $this->configManager->need('mail.address');
$fromName = $this->optionManager->need('client.name.short') . ' ' . $this->optionManager->need('service.name.full');
$replyToAddress = $this->optionManager->need('client.contact.email');
$replyToName = $this->optionManager->need('client.name.full');
$toAddress = $recipient->need('email');
$toName = $recipient->need('alias');
$text = sprintf("%s %s,\r\n\r\n%s\r\n\r\n%s,\r\n%s %s\r\n%s",
$this->t('Dear'), $toName, $text, $this->t('Sincerely'), $this->t("Your"), $fromName, $this->optionManager->need('service.website'));
$this->baseMailService->sendPlain($fromAddress, $fromName, $replyToAddress, $replyToName, $toAddress, $toName, $subject, $text, $attachments);
}
}
================================================
FILE: module/User/src/User/Service/MailServiceFactory.php
================================================
get('Base\Service\MailService');
$configManager = $sm->get('Base\Manager\ConfigManager');
$optionManager = $sm->get('Base\Manager\OptionManager');
return new MailService($mailService, $configManager, $optionManager);
}
}
================================================
FILE: module/User/src/User/Table/UserMetaTable.php
================================================
get('Zend\Db\Adapter\Adapter'));
}
}
================================================
FILE: module/User/src/User/Table/UserTable.php
================================================
get('Zend\Db\Adapter\Adapter'));
}
}
================================================
FILE: module/User/src/User/View/Helper/LastBookings.php
================================================
bookingManager = $bookingManager;
$this->reservationManager = $reservationManager;
$this->squareManager = $squareManager;
}
public function __invoke(User $user)
{
$view = $this->getView();
$userBookings = $this->bookingManager->getByValidity(array(
'uid' => $user->need('uid'),
));
if ($userBookings) {
$this->reservationManager->getByBookings($userBookings);
$now = new DateTime();
$lowerLimit = clone $now;
$lowerLimit->modify('-2 days');
$upperLimit = clone $now;
$upperLimit->modify('+28 days');
$html = '';
$html .= '
= $this->t('If you did not receive an activation email from us after registration, you can request a new one here.') ?>
= $this->t('Therefore, please type the email adress you used for registration.') ?>
= sprintf($this->t('Welcome to our %s'), $this->option('service.name.full')) ?>
= sprintf(
$this->t('You probably guessed it: To use our service, that is to book spare %s online, you need to create your own user account first.'),
$this->option('subject.square.type.plural')) ?>
= $this->t('The registration is of course free of cost and nonbinding.') ?>
option('service.user.registration') == 'false') {
if ($this->option('service.user.registration.message')) {
echo '
= sprintf($this->t('If you have already registered, you can login here with your email address and start booking %s.'),
$this->option('subject.square.type.plural')) ?>
result) {
case true:
echo $this->message(sprintf($this->t('Bye, %s'), $this->user->need('alias')), 'success');
break;
case false:
default:
echo $this->message($this->t('You are not logged in (anymore)'), 'info');
break;
}
?>
');
}
});
})();
================================================
FILE: public/js/controller/square/booking/customization.js
================================================
(function() {
$(document).ready(function() {
$("#sb-customization-panel-warning").remove();
$("#sb-customization-panel").show();
$("#sb-quantity").on("change keyup focusout", onQuantityChange);
onQuantityChange();
$(".sb-player-names input").on("change keyup focusout", onPlayerNameUpdate);
$(".sb-product").on("change", onProductChange);
});
function onQuantityChange() {
var quantity = $("#sb-quantity").val();
var sbButton = $("#sb-button");
if (sbButton.length) {
var oldHref = sbButton.attr("href");
var newHref = oldHref.replace(/q=[0-9]+/, "q=" + quantity);
sbButton.attr("href", newHref);
}
var askNamesPanel = $(".sb-player-names");
if (askNamesPanel.length) {
if (quantity > 1) {
$(".sb-player-name").hide();
for (var i = 2; i <= quantity; i++) {
$(".sb-player-name-" + i).show();
}
askNamesPanel.show();
} else {
askNamesPanel.hide();
}
$(window).trigger("squarebox.update");
}
onPlayerNameUpdate();
}
function onPlayerNameUpdate() {
var sbButton = $("#sb-button");
if (sbButton.length) {
var quantity = $("#sb-quantity").val();
var playerNameMode = $(".sb-player-names-mode").data("mode");
var playerNameInputs = $(".sb-player-names input:visible");
if (quantity > 1) {
var playerNameData = playerNameInputs.serializeArray();
var playerNameJson = JSON.stringify(playerNameData);
var playerNameQuery = "pn=" + encodeURIComponent(playerNameJson);
} else {
var playerNameQuery = "pn=0";
}
sbButton.css({ opacity: 1 });
if (playerNameMode == "required") {
playerNameInputs.each(function() {
if (! $(this).val()) {
sbButton.css({ opacity: 0 });
}
});
}
var oldHref = sbButton.attr("href");
var newHref = oldHref.replace(/pn=[^&]+/, playerNameQuery);
sbButton.attr("href", newHref);
}
}
function onProductChange() {
var sbButton = $("#sb-button");
if (sbButton.length) {
var products = "";
$(".sb-product").each(function(index, element) {
var spid = $(element).data("spid");
var value = $(element).val();
if (value > 0) {
products += spid + ":" + value + ",";
}
});
if (products) {
products = products.substr(0, products.length - 1);
} else {
products = "0";
}
var oldHref = sbButton.attr("href");
var newHref = oldHref.replace(/p=[0-9\:\,]+/, "p=" + products);
sbButton.attr("href", newHref);
}
}
})();
================================================
FILE: public/js/controller/square/index.free.js
================================================
(function() {
$(document).ready(function() {
var buttonBook = $("#sb-button");
/* Alternate time choice */
var at = $("#sb-alternate-times");
if (at.length) {
var buttonReload = $("#sb-reload-button");
at.on("change", function() {
var hrefBook = buttonBook.attr("href");
var hrefReload = buttonReload.attr("href");
if (at.val()) {
var choice = at.val();
buttonBook.attr("href", hrefBook.replace(/\&te\=[0-9][0-9]:[0-9][0-9]/, "&te=" + choice));
buttonReload.attr("href", hrefReload.replace(/\&te\=[0-9][0-9]:[0-9][0-9]/, "&te=" + choice));
buttonReload.click();
}
});
at.show();
}
/* Alternate date choice */
var ad = $("#sb-alternate-date");
if (ad.length) {
ad.on("change", "#sb-date-start-choice, #sb-date-end-choice, #sb-time-start-choice, #sb-time-end-choice", function() {
var alteredHref = buttonBook.attr("href");
alteredHref = alteredHref.replace(/ds=[^&]+/, "ds=" + ad.find("#sb-date-start-choice").val());
alteredHref = alteredHref.replace(/de=[^&]+/, "de=" + ad.find("#sb-date-end-choice").val());
alteredHref = alteredHref.replace(/ts=[^&]+/, "ts=" + ad.find("#sb-time-start-choice").val());
alteredHref = alteredHref.replace(/te=[^&]+/, "te=" + ad.find("#sb-time-end-choice").val());
alteredHref = alteredHref.replace(/\/booking\/customization/, "");
buttonBook.attr("href", alteredHref);
buttonBook.find("span").attr("class", "symbolic symbolic-reload").text(ad.data("sb-new-button"));
});
ad.show();
}
});
})();
================================================
FILE: public/js/controller/user/registration.js
================================================
(function() {
$(document).ready(function() {
var firstnameLabel = $('label[for="rf-firstname"]');
var firstnameLabelOriginal = firstnameLabel.text();
var firstnameInput = $("#rf-firstname");
var lastnameInput = $("#rf-lastname");
var firstnameInputOriginal = firstnameInput.width();
var phoneInput = $("#rf-phone");
var birthdateInput = $("#rf-birthdate");
var genericLabel = $("#rf-generic-label").text();
function updateRegistrationForm()
{
var genderSelect = $("#rf-gender");
if (genderSelect.val() === "family" || genderSelect.val() === "firm") {
firstnameInput.css("width", phoneInput.css("width"));
lastnameInput.hide();
birthdateInput.closest("tr").hide();
firstnameLabel.html(genericLabel);
} else {
firstnameInput.css("width", firstnameInputOriginal);
lastnameInput.show();
birthdateInput.closest("tr").show();
firstnameLabel.html(firstnameLabelOriginal);
}
}
$(document).ready(updateRegistrationForm);
$("#rf-gender").change(updateRegistrationForm);
/* Security related */
if ($("#form-nickname-error").length) {
$('input[name="rf-nickname"]').show();
}
});
})();
================================================
FILE: public/js/controller/user/settings.js
================================================
(function() {
$(document).ready(function() {
var editPanels = $(".edit-panel");
editPanels.hide();
var editLabels = $(".edit-label");
editLabels.css("cursor", "pointer");
editLabels.hover(function() {
$(this).css("color", "#333");
}, function() {
$(this).css("color", "");
});
editLabels.click(function() {
var that = $(this);
if (that.siblings(".edit-panel").is(":hidden")) {
that.closest(".sandbox").siblings(".sandbox").find(".edit-panel:visible").slideUp();
that.siblings(".edit-panel").slideDown();
} else {
that.siblings(".edit-panel").slideUp();
}
});
/* Sandboxes with error messages should be visible */
editPanels.each(function() {
var that = $(this);
if (that.find(".message").length) {
that.show();
}
});
});
})();
================================================
FILE: public/js/default.js
================================================
(function() {
$(document).ready(function() {
/* Autofocus */
$(".autofocus").focus();
/* Messages */
$(".message").each(prepareMessage);
$(document).on("click", ".dismiss-message-link", dismissMessage);
/* Inline labels */
$(".inline-label").find("span").show();
$(".inline-label-container").each(function() {
updateInlineLabel( $(this) );
});
$(document).on("change focus focusin focusout blur keydown", ".inline-label-container", function() {
updateInlineLabel( $(this) );
});
/* Datepickers */
$(document).ready(prepareDatepicker);
$(".datepicker").datepicker();
/* Tooltips */
$(document).tooltip({
"content": function() {
return $(this).data("tooltip");
},
"items": "[data-tooltip]",
"position": { "my": "center top+8", "at": "center bottom", "collision": "flipfit", "within": "#content" }
});
/* Links panel */
$(window).resize(updateLinksPanel);
$(document).ready(updateLinksPanel);
$(document).on("updateLayout", updateLinksPanel);
/* Popup links */
$(document).on("click", "a.popup-link", openPopup);
});
function updateLinksPanel()
{
var linksPanel = $(".links").first();
var targetPanel = $("#content > .centered-panel.content-panel").first();
if (! targetPanel.length) {
targetPanel = $("#content > .centered-panel").first();
}
if (linksPanel.length && targetPanel.length) {
var targetPanelWidth = targetPanel.outerWidth();
var targetPanelMarginTop = parseInt(targetPanel.css("margin-top"));
var targetPanelMarginLeft = parseInt(targetPanel.css("margin-left"));
if (isNaN(targetPanelMarginTop)) {
targetPanelMarginTop = 0;
}
if (isNaN(targetPanelMarginLeft)) {
targetPanelMarginLeft = 0;
}
/* Determine back links */
var linksBack = linksPanel.find(".links-back").first();
var linksBackWidth = 0;
if (linksBack.length) {
linksBack.css("position", "absolute");
linksBackWidth = linksBack.outerWidth(true);
}
/* Determine forth links */
var linksForth = linksPanel.find(".links-forth").first();
var linksForthWidth = 0;
if (linksForth.length) {
linksForth.css("position", "absolute");
linksForthWidth = linksForth.outerWidth(true);
}
/* Determine overall reference width */
var referenceWidth = targetPanelWidth + Math.max(linksBackWidth, linksForthWidth) * 2;
/* Determine links panel display mode */
if (referenceWidth >= $(window).width()) {
linksBack.removeAttr("style");
linksForth.removeAttr("style");
} else {
var targetPanelLeft;
if (targetPanelMarginLeft > 0) {
var targetParentPaddingLeft = parseInt(targetPanel.parent().css("padding-left"));
if (isNaN(targetParentPaddingLeft)) {
targetParentPaddingLeft = 0;
}
targetPanelLeft = targetPanelMarginLeft + targetParentPaddingLeft;
} else {
targetPanelLeft = Math.floor(targetPanel.position().left);
}
linksBack.css({
"left": targetPanelLeft - linksBackWidth,
"top": Math.min(targetPanel.position().top + targetPanelMarginTop + Math.round(targetPanel.outerHeight() / 2) - Math.round(linksBack.outerHeight() / 2), 384)
});
linksForth.css({
"left": targetPanelLeft + targetPanelWidth,
"top": Math.min(targetPanel.position().top + targetPanelMarginTop + Math.round(targetPanel.outerHeight() / 2) - Math.round(linksForth.outerHeight() / 2), 384)
});
}
}
}
function prepareMessage(index)
{
var that = $(this);
blink(that, index * 100);
if (that.is(".default-message, .success-message, .info-message, .error-message")) {
if (that.closest(".messages-panel").siblings(".centered-panel").length) {
that.prepend('×');
}
}
}
function dismissMessage(event)
{
event.preventDefault();
var messagesPanel = $(this).closest(".messages-panel");
var messages = messagesPanel.find(".message");
if (messages.length) {
var message = $(this).closest(".message");
message.fadeOut(500, function() {
message.remove();
$(document).trigger("updateLayout");
});
} else {
messagesPanel.fadeOut(500, function() {
messagesPanel.remove();
$(document).trigger("updateLayout");
});
}
}
function prepareDatepicker()
{
var locale = $("html").attr("lang");
var basePath = $("#logo").attr("href");
if (locale && locale !== "en-US") {
$("body").append('');
}
$.datepicker.setDefaults({
"altFormat": "M d, yy",
"dateFormat": "M d, yy",
"onSelect": function() {
that = $(this);
that.trigger("change");
updateInlineLabel(that);
if (that.is(".datepicker-autosubmit")) {
that.closest("form").submit();
}
},
"showAnim": "slideDown"
});
}
function openPopup(event)
{
var link = $(this);
var popup = window.open(link.attr("href"), "bs-popup", "dependent=yes,height=512,left=64,location=no,menubar=no,resizable=yes,top=64,width=1024");
if (! (! popup || popup.closed || typeof popup.closed=='undefined')) {
event.preventDefault();
}
}
})();
function updateInlineLabel(input)
{
var label = input.siblings(".inline-label");
if (label.length) {
if (input.val()) {
label.find("span").clearQueue().hide();
} else if (input.is(":focus")) {
label.find("span").clearQueue().delay(100).fadeOut(300);
} else {
label.find("span").clearQueue().delay(100).fadeIn(300);
}
}
}
function blink(element, delay, length, strength)
{
if (! element) {
return;
}
if (! delay) {
delay = 0;
}
if (! length) {
length = 300;
}
if (! strength) {
strength = 0.25;
}
element.delay(delay).fadeTo(length, strength, function() {
element.fadeTo(length, 1.0);
});
}
================================================
FILE: public/js/jquery-ui/i18n/de-DE.js
================================================
jQuery(function($) {
$.datepicker.regional["de"] = {
"altFormat": "dd.mm.yy",
"closeText": "Schließen",
"currentText": "Heute",
"dateFormat": "dd.mm.yy",
"dayNames": ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"],
"dayNamesMin": ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"],
"dayNamesShort": ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"],
"firstDay": 1,
"monthNames": ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"],
"monthNamesShort": ["Jan", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"],
"nextText": "Vor",
"prevText": "Zurück"
};
$.datepicker.setDefaults($.datepicker.regional["de"]);
});
================================================
FILE: public/js/jquery-ui/i18n/fr-FR.js
================================================
jQuery(function($) {
$.datepicker.regional["fr"] = {
"altFormat": "dd.mm.yy",
"closeText": "Fermer",
"currentText": "Aujourd'hui",
"dateFormat": "dd.mm.yy",
"dayNames": [ "dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi" ],
"dayNamesMin": [ "D","L","M","M","J","V","S" ],
"dayNamesShort": [ "dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam." ],
"firstDay": 1,
"monthNames": [ "janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre" ],
"monthNamesShort": [ "janv.", "févr.", "mars", "avr.", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc." ],
"nextText": "Suivant",
"prevText": "Précédent"
};
$.datepicker.setDefaults($.datepicker.regional["fr"]);
});
================================================
FILE: public/js/jquery-ui/i18n/hu-HU.js
================================================
jQuery(function($) {
$.datepicker.regional["hu"] = {
"altFormat": "dd.mm.yy",
"closeText": "Bezár",
"currentText": "Ma",
"dateFormat": "dd.mm.yy",
"dayNames": ["Vasárnap", "Hétfő", "Kedd", "Szerda", "Csütörtök", "Péntek", "Szombat"],
"dayNamesMin": ["Va", "Hé", "Ke", "Sze", "Cs", "Pé", "Szo"],
"dayNamesShort": ["Va", "Hé", "Ke", "Sze", "Cs", "Pé", "Szo"],
"firstDay": 1,
"monthNames": ["Január", "Február", "Március", "Április", "Május", "Június", "Július", "Augusztus", "Szeptember", "Október", "November", "December"],
"monthNamesShort": ["Jan", "Feb", "Már", "Ápr", "Máj", "Jún", "Júl", "Aug", "Szep", "Okt", "Nov", "Dec"],
"nextText": "Következő",
"prevText": "Előző"
};
$.datepicker.setDefaults($.datepicker.regional["hu"]);
});
================================================
FILE: public/js/tinymce/langs/de-DE.js
================================================
tinymce.addI18n('de', {
"Cut": "Ausschneiden",
"Header 2": "\u00dcberschrift 2",
"Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": "Ihr Browser unterst\u00fctzt leider keinen direkten Zugriff auf die Zwischenablage. Bitte benutzen Sie die Tastenkombination Strg+X\/C\/V.",
"Div": "Allgemeiner Block",
"Paste": "Einf\u00fcgen",
"Close": "Schließen",
"Pre": "Vorformatierter Text",
"Align right": "Rechtsbündig",
"New document": "Neues Dokument",
"Blockquote": "Zitat",
"Numbered list": "Geordnete Liste",
"Increase indent": "Einzug vergrößern",
"Formats": "Formate",
"Headers": "\u00dcberschrift",
"Select all": "Alles ausw\u00e4hlen",
"Header 3": "\u00dcberschrift 3",
"Blocks": "Textblock",
"Undo": "Rückgängig",
"Strikethrough": "Durchgestrichen",
"Bulleted list": "Ungeordnete Liste",
"Header 1": "\u00dcberschrift 1",
"Superscript": "Hochgestellt",
"Clear formatting": "Formatierung bereinigen",
"Subscript": "Tiefgestellt",
"Header 6": "\u00dcberschrift 6",
"Redo": "Wiederholen",
"Paragraph": "Absatz",
"Ok": "Ok",
"Bold": "Fett",
"Code": "Quelltext",
"Italic": "Kursiv",
"Align center": "Zentriert",
"Header 5": "\u00dcberschrift 5",
"Decrease indent": "Einzug verringern",
"Header 4": "\u00dcberschrift 4",
"Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.": "Einf\u00fcgungen erfolgen nun als unformatierter Text.",
"Underline": "Unterstrichen",
"Cancel": "Abbrechen",
"Justify": "Blocksatz",
"Inline": "Schriftart",
"Copy": "Kopieren",
"Align left": "Linksbündig",
"Visual aids": "Visuelle Hilfen",
"Lower Greek": "Lower Greek",
"Square": "Quadrat",
"Default": "Standard",
"Lower Alpha": "Lower Alpha",
"Circle": "Kreis",
"Disc": "Disk",
"Upper Alpha": "Upper Alpha",
"Upper Roman": "Upper Roman",
"Lower Roman": "Lower Roman",
"Name": "Name",
"Anchor": "Textanker",
"You have unsaved changes are you sure you want to navigate away?": "Sie haben Ihre Änderungen noch nicht gespeichert, wollen Sie sicher verlassen?",
"Restore last draft": "Letzten Entwurf wiederherstellen",
"Special character": "Sonderzeichen",
"Source code": "Quellcode",
"Right to left": "Links nach Rechts",
"Left to right": "Rechts nach Links",
"Emoticons": "Emoticons",
"Robots": "Robots",
"Document properties": "Dokumenteigenschaften",
"Title": "Titel",
"Keywords": "Sch\u00fcsselw\u00f6rter",
"Encoding": "Zeichensatz",
"Description": "Beschreibung",
"Author": "Autor",
"Fullscreen": "Vollbild",
"Horizontal line": "Horizontale Linie",
"Horizontal space": "Horizontaler Freiraum",
"Insert\/edit image": "Bild einfügen/bearbeiten",
"General": "Allgemein",
"Advanced": "Fortgeschritten",
"Source": "Quelle",
"Border": "Rahmen",
"Constrain proportions": "Proportionen erhalten",
"Vertical space": "Vertikaler Freiraum",
"Image description": "Bild-Beschreibung",
"Style": "Stil",
"Dimensions": "Größe",
"Insert image": "Bild einf\u00fcgen",
"Insert date\/time": "Datum\/Uhrzeit einf\u00fcgen",
"Remove link": "Link entfernen",
"Url": "Url",
"Text to display": "Text zum Anzeigen",
"Insert link": "Link einf\u00fcgen",
"New window": "Neues Fenster",
"None": "Nichts",
"Target": "Ziel",
"Insert\/edit link": "Link einf\u00fcgen\/bearbeiten",
"Insert\/edit video": "Video einf\u00fcgen\/bearbeiten",
"Poster": "Poster",
"Alternative source": "Alternative Quelle",
"Paste your embed code below:": "F\u00fcgen Sie Ihren Code hier ein:",
"Insert video": "Video einf\u00fcgen",
"Embed": "Einbetten",
"Nonbreaking space": "Geschütztes Leerzeichen",
"Page break": "Seitenumbruch",
"Preview": "Vorschau",
"Print": "Drucken",
"Save": "Speichern",
"Could not find the specified string.": "Zeichenfolge wurde nicht gefunden.",
"Replace": "Ersetzen",
"Next": "N\u00e4chstes",
"Whole words": "Ganze W\u00f6rter",
"Find and replace": "Finden und ersetzen",
"Replace with": "Ersetzen mit",
"Find": "Finden",
"Replace all": "Alles ersetzen",
"Match case": "Gro\u00df-\/Kleinschreibung",
"Prev": "Vor",
"Spellcheck": "Rechtschreibpr\u00fcfung",
"Finish": "Ende",
"Ignore all": "Alles Ignorieren",
"Ignore": "Ignorieren",
"Insert row before": "Zeile einf\u00fcgen bevor",
"Rows": "Zeilen",
"Height": "H\u00f6he",
"Paste row after": "Zeile einf\u00fcgen danach",
"Alignment": "Ausrichtung",
"Column group": "Spalten gruppen",
"Row": "Zeile",
"Insert column before": "Spalte einf\u00fcgen bevor",
"Split cell": "Zelle teile",
"Cell padding": "Zelle-Innenabstand",
"Cell spacing": "Zelle-Außenabstand",
"Row type": "Zeilentyp",
"Insert table": "Tabelle einf\u00fcgen",
"Body": "K\u00f6rper",
"Caption": "Titel",
"Footer": "Fu\u00dfzeile",
"Delete row": "Zeile l\u00f6schen",
"Paste row before": "Zeile einf\u00fcgen bevor",
"Scope": "Bereich",
"Delete table": "Tabelle l\u00f6schen",
"Header cell": "Kopfzelle",
"Column": "Spalte",
"Cell": "Zelle",
"Header": "Kopf",
"Cell type": "Zellentyp",
"Copy row": "Zeile Kopieren",
"Row properties": "Zeilen-Eingeschaften",
"Table properties": "Tabellen-Eigenschaften",
"Row group": "Zeilengruppe",
"Right": "Rechts",
"Insert column after": "Spalte einf\u00fcgen danach",
"Cols": "Spalten",
"Insert row after": "Zeile einf\u00fcgen danach",
"Width": "Breite",
"Cell properties": "Zellen-Eigenschaften",
"Left": "Links",
"Cut row": "Zeile ausschneiden",
"Delete column": "Spalte l\u00f6schen",
"Center": "Zentriert",
"Merge cells": "Zellen verbinden",
"Insert template": "Vorlage einf\u00fcgen",
"Templates": "Vorlagen",
"Background color": "Hintergrundfarbe",
"Text color": "Vordergrundfarbe",
"Show blocks": "Bl\u00f6cke anzeigen",
"Show invisible characters": "Unsichtbare Zeichen anzeigen",
"Words: {0}": "W\u00f6rter: {0}",
"Insert": "Einf\u00fcgen",
"File": "Datei",
"Edit": "Bearbeiten",
"Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help": "Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help",
"Tools": "Werkzeuge",
"View": "Anzeigen",
"Table": "Tabelle",
"Format": "Format"
});
================================================
FILE: public/js/tinymce/langs/fr-FR.js
================================================
tinymce.addI18n('fr',{
"Cut": "Couper",
"Header 2": "Titre 2",
"Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": "Votre navigateur ne supporte pas la copie directe. Merci d'utiliser les touches Ctrl+X\/C\/V.",
"Div": "Div",
"Paste": "Coller",
"Close": "Fermer",
"Font Family": "Polices de caract\u00e8res",
"Pre": "Pre",
"Align right": "Aligner \u00e0 droite",
"New document": "Nouveau document",
"Blockquote": "Citation",
"Numbered list": "Num\u00e9rotation",
"Increase indent": "Augmenter le retrait",
"Formats": "Formats",
"Headers": "Titres",
"Select all": "Tout s\u00e9lectionner",
"Header 3": "Titre 3",
"Blocks": "Blocs",
"Undo": "Annuler",
"Strikethrough": "Barr\u00e9",
"Bullet list": "Puces",
"Header 1": "Titre 1",
"Superscript": "Exposant",
"Clear formatting": "Effacer la mise en forme",
"Font Sizes": "Tailles de la police",
"Subscript": "Indice",
"Header 6": "Titre 6",
"Redo": "R\u00e9tablir",
"Paragraph": "Paragraphe",
"Ok": "Ok",
"Bold": "Gras",
"Code": "Code",
"Italic": "Italique",
"Align center": "Aligner au centre",
"Header 5": "Titre 5",
"Decrease indent": "Diminuer le retrait",
"Header 4": "Titre 4",
"Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.": "Le presse-papiers est maintenant en mode \"texte plein\". Les contenus seront coll\u00e9s sans retenir les formatages jusqu'\u00e0 ce que vous d\u00e9sactiviez cette option.",
"Underline": "Soulign\u00e9",
"Cancel": "Annuler",
"Justify": "Justifi\u00e9",
"Inline": "En ligne",
"Copy": "Copier",
"Align left": "Aligner \u00e0 gauche",
"Visual aids": "Aides visuelle",
"Lower Greek": "Grec minuscule",
"Square": "Carr\u00e9",
"Default": "Par d\u00e9faut",
"Lower Alpha": "Alpha minuscule",
"Circle": "Cercle",
"Disc": "Disque",
"Upper Alpha": "Alpha majuscule",
"Upper Roman": "Romain majuscule",
"Lower Roman": "Romain minuscule",
"Name": "Nom",
"Anchor": "Ancre",
"You have unsaved changes are you sure you want to navigate away?": "Vous avez des modifications non enregistr\u00e9es, \u00eates-vous s\u00fbr de quitter la page?",
"Restore last draft": "Restaurer le dernier brouillon",
"Special character": "Caract\u00e8res sp\u00e9ciaux",
"Source code": "Code source",
"Right to left": "Droite \u00e0 gauche",
"Left to right": "Gauche \u00e0 droite",
"Emoticons": "Emotic\u00f4nes",
"Robots": "Robots",
"Document properties": "Propri\u00e9t\u00e9 du document",
"Title": "Titre",
"Keywords": "Mots-cl\u00e9s",
"Encoding": "Encodage",
"Description": "Description",
"Author": "Auteur",
"Fullscreen": "Plein \u00e9cran",
"Horizontal line": "Ligne horizontale",
"Horizontal space": "Espacement horizontal",
"Insert\/edit image": "Ins\u00e9rer\/\u00e9diter une image",
"General": "G\u00e9n\u00e9ral",
"Advanced": "Avanc\u00e9",
"Source": "Source",
"Border": "Bordure",
"Constrain proportions": "Contraindre les proportions",
"Vertical space": "Espacement vertical",
"Image description": "Description de l'image",
"Style": "Style",
"Dimensions": "Dimensions",
"Insert image": "Ins\u00e9rer une image",
"Insert date\/time": "Ins\u00e9rer date\/heure",
"Remove link": "Enlever le lien",
"Url": "Url",
"Text to display": "Texte \u00e0 afficher",
"Anchors": "Ancres",
"Insert link": "Ins\u00e9rer un lien",
"New window": "Nouvelle fen\u00eatre",
"None": "n\/a",
"The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?": "L'URL que vous avez entr\u00e9e semble \u00eatre un lien externe. Voulez-vous ajouter le pr\u00e9fixe http:\/\/ n\u00e9cessaire?",
"Target": "Cible",
"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "L'URL que vous avez entr\u00e9e semble \u00eatre une adresse e-mail. Voulez-vous ajouter le pr\u00e9fixe mailto: n\u00e9cessaire?",
"Insert\/edit link": "Ins\u00e9rer\/\u00e9diter un lien",
"Insert\/edit video": "Ins\u00e9rer\/\u00e9diter une vid\u00e9o",
"Poster": "Publier",
"Alternative source": "Source alternative",
"Paste your embed code below:": "Collez votre code d'int\u00e9gration ci-dessous :",
"Insert video": "Ins\u00e9rer une vid\u00e9o",
"Embed": "Ins\u00e9rer",
"Nonbreaking space": "Espace ins\u00e9cable",
"Page break": "Saut de page",
"Paste as text": "Coller comme texte",
"Preview": "Pr\u00e9visualiser",
"Print": "Imprimer",
"Save": "Enregistrer",
"Could not find the specified string.": "Impossible de trouver la cha\u00eene sp\u00e9cifi\u00e9e.",
"Replace": "Remplacer",
"Next": "Suiv",
"Whole words": "Mots entiers",
"Find and replace": "Trouver et remplacer",
"Replace with": "Remplacer par",
"Find": "Chercher",
"Replace all": "Tout remplacer",
"Match case": "Respecter la casse",
"Prev": "Pr\u00e9c ",
"Spellcheck": "V\u00e9rification orthographique",
"Finish": "Finie",
"Ignore all": "Tout ignorer",
"Ignore": "Ignorer",
"Insert row before": "Ins\u00e9rer une ligne avant",
"Rows": "Lignes",
"Height": "Hauteur",
"Paste row after": "Coller la ligne apr\u00e8s",
"Alignment": "Alignement",
"Column group": "Groupe de colonnes",
"Row": "Ligne",
"Insert column before": "Ins\u00e9rer une colonne avant",
"Split cell": "Diviser la cellule",
"Cell padding": "Espacement interne cellule",
"Cell spacing": "Espacement inter-cellulles",
"Row type": "Type de ligne",
"Insert table": "Ins\u00e9rer un tableau",
"Body": "Corps",
"Caption": "Titre",
"Footer": "Pied",
"Delete row": "Effacer la ligne",
"Paste row before": "Coller la ligne avant",
"Scope": "Etendue",
"Delete table": "Supprimer le tableau",
"H Align": "Alignement H",
"Top": "Haut",
"Header cell": "Cellule d'en-t\u00eate",
"Column": "Colonne",
"Row group": "Groupe de lignes",
"Cell": "Cellule",
"Middle": "Milieu",
"Cell type": "Type de cellule",
"Copy row": "Copier la ligne",
"Row properties": "Propri\u00e9t\u00e9s de la ligne",
"Table properties": "Propri\u00e9t\u00e9s du tableau",
"Bottom": "Bas",
"V Align": "Alignement V",
"Header": "En-t\u00eate",
"Right": "Droite",
"Insert column after": "Ins\u00e9rer une colonne apr\u00e8s",
"Cols": "Colonnes",
"Insert row after": "Ins\u00e9rer une ligne apr\u00e8s",
"Width": "Largeur",
"Cell properties": "Propri\u00e9t\u00e9s de la cellule",
"Left": "Gauche",
"Cut row": "Couper la ligne",
"Delete column": "Effacer la colonne",
"Center": "Centr\u00e9",
"Merge cells": "Fusionner les cellules",
"Insert template": "Ajouter un th\u00e8me",
"Templates": "Th\u00e8mes",
"Background color": "Couleur d'arri\u00e8re-plan",
"Text color": "Couleur du texte",
"Show blocks": "Afficher les blocs",
"Show invisible characters": "Afficher les caract\u00e8res invisibles",
"Words: {0}": "Mots : {0}",
"Insert": "Ins\u00e9rer",
"File": "Fichier",
"Edit": "Editer",
"Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help": "Zone Texte Riche. Appuyer sur ALT-F9 pour le menu. Appuyer sur ALT-F10 pour la barre d'outils. Appuyer sur ALT-0 pour de l'aide.",
"Tools": "Outils",
"View": "Voir",
"Table": "Tableau",
"Format": "Format"
});
================================================
FILE: public/js/tinymce/langs/hu-HU.js
================================================
tinymce.addI18n('hu_HU',{
"Redo": "Ism\u00e9t",
"Undo": "Visszavon\u00e1s",
"Cut": "Kiv\u00e1g\u00e1s",
"Copy": "M\u00e1sol\u00e1s",
"Paste": "Beilleszt\u00e9s",
"Select all": "Minden kijel\u00f6l\u00e9se",
"New document": "\u00daj dokumentum",
"Ok": "Rendben",
"Cancel": "M\u00e9gse",
"Visual aids": "Vizu\u00e1lis seg\u00e9deszk\u00f6z\u00f6k",
"Bold": "F\u00e9lk\u00f6v\u00e9r",
"Italic": "D\u0151lt",
"Underline": "Al\u00e1h\u00fazott",
"Strikethrough": "\u00c1th\u00fazott",
"Superscript": "Fels\u0151 index",
"Subscript": "Als\u00f3 index",
"Clear formatting": "Form\u00e1z\u00e1s t\u00f6rl\u00e9se",
"Align left": "Balra igaz\u00edt",
"Align center": "K\u00f6z\u00e9pre z\u00e1r",
"Align right": "Jobbra igaz\u00edt",
"Justify": "Sorkiz\u00e1r\u00e1s",
"Bullet list": "Felsorol\u00e1s",
"Numbered list": "Sz\u00e1moz\u00e1s",
"Decrease indent": "Beh\u00faz\u00e1s cs\u00f6kkent\u00e9se",
"Increase indent": "Beh\u00faz\u00e1s n\u00f6vel\u00e9se",
"Close": "Bez\u00e1r",
"Formats": "Form\u00e1tumok",
"Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": "A b\u00f6ng\u00e9sz\u0151d nem t\u00e1mogatja a k\u00f6zvetlen hozz\u00e1f\u00e9r\u00e9st a v\u00e1g\u00f3laphoz. K\u00e9rlek haszn\u00e1ld a Ctrl+X\/C\/V billenty\u0171ket.",
"Headers": "C\u00edmsorok",
"Header 1": "C\u00edmsor 1",
"Header 2": "C\u00edmsor 2",
"Header 3": "C\u00edmsor 3",
"Header 4": "C\u00edmsor 4",
"Header 5": "C\u00edmsor 5",
"Header 6": "C\u00edmsor 6",
"Headings": "Fejl\u00e9cek",
"Heading 1": "Fejl\u00e9c 1",
"Heading 2": "Fejl\u00e9c 2",
"Heading 3": "Fejl\u00e9c 3",
"Heading 4": "Fejl\u00e9c 4",
"Heading 5": "Fejl\u00e9c 5",
"Heading 6": "Fejl\u00e9c 6",
"Preformatted": "El\u0151form\u00e1zott",
"Div": "Div",
"Pre": "El\u0151form\u00e1zott",
"Code": "K\u00f3d",
"Paragraph": "Bekezd\u00e9s",
"Blockquote": "Id\u00e9zetblokk",
"Inline": "Sz\u00f6vegk\u00f6zi",
"Blocks": "Blokkok",
"Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.": "Beilleszt\u00e9s mostant\u00f3l egyszer\u0171 sz\u00f6veg m\u00f3dban. A tartalmak mostant\u00f3l egyszer\u0171 sz\u00f6vegk\u00e9nt lesznek beillesztve, am\u00edg nem kapcsolod ki ezt az opci\u00f3t.",
"Font Family": "Bet\u0171t\u00edpus",
"Font Sizes": "Bet\u0171m\u00e9retek",
"Class": "Oszt\u00e1ly",
"Browse for an image": "K\u00e9p tall\u00f3z\u00e1sa",
"OR": "vagy",
"Drop an image here": "Dobj ide egy k\u00e9pet",
"Upload": "Felt\u00f6lt\u00e9s",
"Block": "Blokk",
"Align": "Igaz\u00edt\u00e1s",
"Default": "Alap\u00e9rtelmezett",
"Circle": "K\u00f6r",
"Disc": "Pont",
"Square": "N\u00e9gyzet",
"Lower Alpha": "Kisbet\u0171",
"Lower Greek": "Kis g\u00f6r\u00f6g sz\u00e1m",
"Lower Roman": "Kis r\u00f3mai sz\u00e1m",
"Upper Alpha": "Nagybet\u0171",
"Upper Roman": "Nagy r\u00f3mai sz\u00e1m",
"Anchor": "Horgony",
"Name": "N\u00e9v",
"Id": "Azonos\u00edt\u00f3",
"Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.": "Az azonos\u00edt\u00f3nak bet\u0171vel kell kezd\u0151dnie, azut\u00e1n csak bet\u0171ket, sz\u00e1mokat, gondolatjeleket, pontokat, kett\u0151spontokat vagy al\u00e1h\u00faz\u00e1st tartalmazhat.",
"You have unsaved changes are you sure you want to navigate away?": "Nem mentett m\u00f3dos\u00edt\u00e1said vannak, biztos hogy el akarsz navig\u00e1lni?",
"Restore last draft": "Utols\u00f3 piszkozat vissza\u00e1ll\u00edt\u00e1sa",
"Special character": "Speci\u00e1lis karakter",
"Source code": "Forr\u00e1sk\u00f3d",
"Insert\/Edit code sample": "K\u00f3dminta besz\u00far\u00e1sa\/szerkeszt\u00e9se",
"Language": "Nyelv",
"Code sample": "K\u00f3d p\u00e9lda",
"Color": "Sz\u00edn",
"R": "R",
"G": "G",
"B": "B",
"Left to right": "Balr\u00f3l jobbra",
"Right to left": "Jobbr\u00f3l balra",
"Emoticons": "Vigyorok",
"Document properties": "Dokumentum tulajdons\u00e1gai",
"Title": "C\u00edm",
"Keywords": "Kulcsszavak",
"Description": "Le\u00edr\u00e1s",
"Robots": "Robotok",
"Author": "Szerz\u0151",
"Encoding": "K\u00f3dol\u00e1s",
"Fullscreen": "Teljes k\u00e9perny\u0151",
"Action": "M\u0171velet",
"Shortcut": "Parancsikon",
"Help": "S\u00fag\u00f3",
"Address": "C\u00edm",
"Focus to menubar": "F\u00f3kusz a men\u00fcre",
"Focus to toolbar": "F\u00f3kusz az eszk\u00f6zt\u00e1rra",
"Focus to element path": "F\u00f3kusz az elemek \u00fatvonal\u00e1ra",
"Focus to contextual toolbar": "F\u00f3kusz a k\u00f6rnyezetf\u00fcgg\u0151 eszk\u00f6zt\u00e1rra",
"Insert link (if link plugin activated)": "Hivatkoz\u00e1s besz\u00far\u00e1sa (ha a hivatkoz\u00e1s b\u0151v\u00edtm\u00e9ny enged\u00e9lyezett)",
"Save (if save plugin activated)": "Ment\u00e9s (ha a ment\u00e9s b\u0151v\u00edtm\u00e9ny enged\u00e9lyezett)",
"Find (if searchreplace plugin activated)": "Keres\u00e9s (ha a keres\u00e9s \u00e9s csere b\u0151v\u00edtm\u00e9ny enged\u00e9lyezett)",
"Plugins installed ({0}):": "Telep\u00edtett b\u0151v\u00edtm\u00e9nyek ({0}):",
"Premium plugins:": "Pr\u00e9mium b\u0151v\u00edtm\u00e9nyek:",
"Learn more...": "Tudj meg t\u00f6bbet...",
"You are using {0}": "Haszn\u00e1latban: {0}",
"Plugins": "Pluginek",
"Handy Shortcuts": "Hasznos linkek",
"Horizontal line": "V\u00edzszintes vonal",
"Insert\/edit image": "K\u00e9p beilleszt\u00e9se\/szerkeszt\u00e9se",
"Image description": "K\u00e9p le\u00edr\u00e1sa",
"Source": "Forr\u00e1s",
"Dimensions": "M\u00e9retek",
"Constrain proportions": "M\u00e9retar\u00e1ny",
"General": "\u00c1ltal\u00e1nos",
"Advanced": "Halad\u00f3",
"Style": "St\u00edlus",
"Vertical space": "Vertik\u00e1lis hely",
"Horizontal space": "Horizont\u00e1lis hely",
"Border": "Szeg\u00e9ly",
"Insert image": "K\u00e9p beilleszt\u00e9se",
"Image": "K\u00e9p",
"Image list": "K\u00e9p lista",
"Rotate counterclockwise": "Forgat\u00e1s az \u00f3ramutat\u00f3 j\u00e1r\u00e1s\u00e1val ellent\u00e9tesen",
"Rotate clockwise": "Forgat\u00e1s az \u00f3ramutat\u00f3 j\u00e1r\u00e1s\u00e1val megegyez\u0151en",
"Flip vertically": "F\u00fcgg\u0151leges t\u00fckr\u00f6z\u00e9s",
"Flip horizontally": "V\u00edzszintes t\u00fckr\u00f6z\u00e9s",
"Edit image": "K\u00e9p szerkeszt\u00e9se",
"Image options": "K\u00e9p be\u00e1ll\u00edt\u00e1sok",
"Zoom in": "Nagy\u00edt\u00e1s",
"Zoom out": "Kicsiny\u00edt\u00e9s",
"Crop": "K\u00e9p v\u00e1g\u00e1s",
"Resize": "\u00c1tm\u00e9retez\u00e9s",
"Orientation": "K\u00e9p t\u00e1jol\u00e1s",
"Brightness": "F\u00e9nyer\u0151",
"Sharpen": "\u00c9less\u00e9g",
"Contrast": "Kontraszt",
"Color levels": "Sz\u00ednszint",
"Gamma": "Gamma",
"Invert": "Inverz k\u00e9p",
"Apply": "Ment\u00e9s",
"Back": "Vissza",
"Insert date\/time": "D\u00e1tum\/id\u0151 beilleszt\u00e9se",
"Date\/time": "D\u00e1tum\/id\u0151",
"Insert link": "Hivatkoz\u00e1s beilleszt\u00e9se",
"Insert\/edit link": "Hivatkoz\u00e1s beilleszt\u00e9se\/szerkeszt\u00e9se",
"Text to display": "Megjelen\u0151 sz\u00f6veg",
"Url": "Url",
"Target": "C\u00e9l",
"None": "Nincs",
"New window": "\u00daj ablak",
"Remove link": "Hivatkoz\u00e1s t\u00f6rl\u00e9se",
"Anchors": "Horgonyok",
"Link": "Hivatkoz\u00e1s",
"Paste or type a link": "Hivatkoz\u00e1s be\u00edr\u00e1sa vagy beilleszt\u00e9se",
"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "A megadott URL email c\u00edmnek t\u0171nik. Szeretn\u00e9d hozz\u00e1adni a sz\u00fcks\u00e9ges mailto: el\u0151tagot?",
"The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?": "A megadott URL k\u00fcls\u0151 c\u00edmnek t\u0171nik. Szeretn\u00e9d hozz\u00e1adni a sz\u00fcks\u00e9ges http:\/\/ el\u0151tagot?",
"Link list": "Hivatkoz\u00e1slista",
"Insert video": "Vide\u00f3 beilleszt\u00e9se",
"Insert\/edit video": "Vide\u00f3 beilleszt\u00e9se\/szerkeszt\u00e9se",
"Insert\/edit media": "M\u00e9dia besz\u00far\u00e1sa\/beilleszt\u00e9se",
"Alternative source": "Alternat\u00edv forr\u00e1s",
"Poster": "El\u0151n\u00e9zeti k\u00e9p",
"Paste your embed code below:": "Illeszd be a be\u00e1gyaz\u00f3 k\u00f3dot alulra:",
"Embed": "Be\u00e1gyaz\u00e1s",
"Media": "M\u00e9dia",
"Nonbreaking space": "Nem t\u00f6rhet\u0151 sz\u00f3k\u00f6z",
"Page break": "Oldalt\u00f6r\u00e9s",
"Paste as text": "Beilleszt\u00e9s sz\u00f6vegk\u00e9nt",
"Preview": "El\u0151n\u00e9zet",
"Print": "Nyomtat\u00e1s",
"Save": "Ment\u00e9s",
"Find": "Keres\u00e9s",
"Replace with": "Csere erre",
"Replace": "Csere",
"Replace all": "Az \u00f6sszes cser\u00e9je",
"Prev": "El\u0151z\u0151",
"Next": "K\u00f6vetkez\u0151",
"Find and replace": "Keres\u00e9s \u00e9s csere",
"Could not find the specified string.": "A be\u00edrt kifejez\u00e9s nem tal\u00e1lhat\u00f3.",
"Match case": "Kis \u00e9s nagybet\u0171k megk\u00fcl\u00f6nb\u00f6ztet\u00e9se",
"Whole words": "Csak ha ez a teljes sz\u00f3",
"Spellcheck": "Helyes\u00edr\u00e1s ellen\u0151rz\u00e9s",
"Ignore": "Figyelmen k\u00edv\u00fcl hagy",
"Ignore all": "Mindent figyelmen k\u00edv\u00fcl hagy",
"Finish": "Befejez\u00e9s",
"Add to Dictionary": "Sz\u00f3t\u00e1rhoz ad",
"Insert table": "T\u00e1bl\u00e1zat beilleszt\u00e9se",
"Table properties": "T\u00e1bl\u00e1zat tulajdons\u00e1gok",
"Delete table": "T\u00e1bl\u00e1zat t\u00f6rl\u00e9se",
"Cell": "Cella",
"Row": "Sor",
"Column": "Oszlop",
"Cell properties": "Cella tulajdons\u00e1gok",
"Merge cells": "Cell\u00e1k egyes\u00edt\u00e9se",
"Split cell": "Cell\u00e1k sz\u00e9tv\u00e1laszt\u00e1sa",
"Insert row before": "Sor besz\u00far\u00e1sa el\u00e9",
"Insert row after": "Sor besz\u00far\u00e1sa m\u00f6g\u00e9",
"Delete row": "Sor t\u00f6rl\u00e9se",
"Row properties": "Sor tulajdons\u00e1gai",
"Cut row": "Sor kiv\u00e1g\u00e1sa",
"Copy row": "Sor m\u00e1sol\u00e1sa",
"Paste row before": "Sor beilleszt\u00e9se el\u00e9",
"Paste row after": "Sor beilleszt\u00e9se m\u00f6g\u00e9",
"Insert column before": "Oszlop besz\u00far\u00e1sa el\u00e9",
"Insert column after": "Oszlop besz\u00far\u00e1sa m\u00f6g\u00e9",
"Delete column": "Oszlop t\u00f6rl\u00e9se",
"Cols": "Oszlopok",
"Rows": "Sorok",
"Width": "Sz\u00e9less\u00e9g",
"Height": "Magass\u00e1g",
"Cell spacing": "Cell\u00e1k t\u00e1vols\u00e1ga",
"Cell padding": "Cella m\u00e9rete",
"Caption": "Felirat",
"Left": "Bal",
"Center": "K\u00f6z\u00e9p",
"Right": "Jobb",
"Cell type": "Cella t\u00edpusa",
"Scope": "Hat\u00f3k\u00f6r",
"Alignment": "Igaz\u00edt\u00e1s",
"H Align": "V\u00edzszintes igaz\u00edt\u00e1s",
"V Align": "F\u00fcgg\u0151leges igaz\u00edt\u00e1s",
"Top": "Fel\u00fcl",
"Middle": "K\u00f6z\u00e9pen",
"Bottom": "Alul",
"Header cell": "Fejl\u00e9c cella",
"Row group": "Sor csoport",
"Column group": "Oszlop csoport",
"Row type": "Sor t\u00edpus",
"Header": "Fejl\u00e9c",
"Body": "Sz\u00f6vegt\u00f6rzs",
"Footer": "L\u00e1bl\u00e9c",
"Border color": "Szeg\u00e9ly sz\u00edne",
"Insert template": "Sablon beilleszt\u00e9se",
"Templates": "Sablonok",
"Template": "Sablon",
"Text color": "Sz\u00f6veg sz\u00edne",
"Background color": "H\u00e1tt\u00e9r sz\u00edn",
"Custom...": "Egy\u00e9ni...",
"Custom color": "Egy\u00e9ni sz\u00edn",
"No color": "Nincs sz\u00edn",
"Table of Contents": "Tartalomjegyz\u00e9k",
"Show blocks": "Blokkok mutat\u00e1sa",
"Show invisible characters": "L\u00e1thatatlan karakterek mutat\u00e1sa",
"Words: {0}": "Szavak: {0}",
"{0} words": "{0} sz\u00f3",
"File": "F\u00e1jl",
"Edit": "Szerkeszt\u00e9s",
"Insert": "Beilleszt\u00e9s",
"View": "N\u00e9zet",
"Format": "Form\u00e1tum",
"Table": "T\u00e1bl\u00e1zat",
"Tools": "Eszk\u00f6z\u00f6k",
"Powered by {0}": "\u00dczemelteti: {0}",
"Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help": "Rich Text ter\u00fclet. Nyomj ALT-F9-et a men\u00fch\u00f6z. Nyomj ALT-F10-et az eszk\u00f6zt\u00e1rhoz. Nyomj ALT-0-t a s\u00fag\u00f3hoz"
});
================================================
FILE: public/js/tinymce/license.txt
================================================
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
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 this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
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
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser 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 Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "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
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY 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
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
Copyright (C)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!
================================================
FILE: public/js/tinymce/plugins/example/dialog.html
================================================
Custom dialog
Input some text:
================================================
FILE: public/js/tinymce/plugins/visualblocks/css/visualblocks.css
================================================
.mce-visualblocks p {
padding-top: 10px;
border: 1px dashed #BBB;
margin-left: 3px;
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhCQAJAJEAAAAAAP///7u7u////yH5BAEAAAMALAAAAAAJAAkAAAIQnG+CqCN/mlyvsRUpThG6AgA7);
}
.mce-visualblocks h1 {
padding-top: 10px;
border: 1px dashed #BBB;
margin-left: 3px;
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGu1JuxHoAfRNRW3TWXyF2YiRUAOw==);
}
.mce-visualblocks h2 {
padding-top: 10px;
border: 1px dashed #BBB;
margin-left: 3px;
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8Hybbx4oOuqgTynJd6bGlWg3DkJzoaUAAAOw==);
}
.mce-visualblocks h3 {
padding-top: 10px;
border: 1px dashed #BBB;
margin-left: 3px;
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIZjI8Hybbx4oOuqgTynJf2Ln2NOHpQpmhAAQA7);
}
.mce-visualblocks h4 {
padding-top: 10px;
border: 1px dashed #BBB;
margin-left: 3px;
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxInR0zqeAdhtJlXwV1oCll2HaWgAAOw==);
}
.mce-visualblocks h5 {
padding-top: 10px;
border: 1px dashed #BBB;
margin-left: 3px;
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxIoiuwjane4iq5GlW05GgIkIZUAAAOw==);
}
.mce-visualblocks h6 {
padding-top: 10px;
border: 1px dashed #BBB;
margin-left: 3px;
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxIoiuwjan04jep1iZ1XRlAo5bVgAAOw==);
}
.mce-visualblocks div {
padding-top: 10px;
border: 1px dashed #BBB;
margin-left: 3px;
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhEgAKAIABALu7u////yH5BAEAAAEALAAAAAASAAoAAAIfjI9poI0cgDywrhuxfbrzDEbQM2Ei5aRjmoySW4pAAQA7);
}
.mce-visualblocks section {
padding-top: 10px;
border: 1px dashed #BBB;
margin: 0 0 1em 3px;
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhKAAKAIABALu7u////yH5BAEAAAEALAAAAAAoAAoAAAI5jI+pywcNY3sBWHdNrplytD2ellDeSVbp+GmWqaDqDMepc8t17Y4vBsK5hDyJMcI6KkuYU+jpjLoKADs=);
}
.mce-visualblocks article {
padding-top: 10px;
border: 1px dashed #BBB;
margin: 0 0 1em 3px;
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhKgAKAIABALu7u////yH5BAEAAAEALAAAAAAqAAoAAAI6jI+pywkNY3wG0GBvrsd2tXGYSGnfiF7ikpXemTpOiJScasYoDJJrjsG9gkCJ0ag6KhmaIe3pjDYBBQA7);
}
.mce-visualblocks blockquote {
padding-top: 10px;
border: 1px dashed #BBB;
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhPgAKAIABALu7u////yH5BAEAAAEALAAAAAA+AAoAAAJPjI+py+0Knpz0xQDyuUhvfoGgIX5iSKZYgq5uNL5q69asZ8s5rrf0yZmpNkJZzFesBTu8TOlDVAabUyatguVhWduud3EyiUk45xhTTgMBBQA7);
}
.mce-visualblocks address {
padding-top: 10px;
border: 1px dashed #BBB;
margin: 0 0 1em 3px;
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhLQAKAIABALu7u////yH5BAEAAAEALAAAAAAtAAoAAAI/jI+pywwNozSP1gDyyZcjb3UaRpXkWaXmZW4OqKLhBmLs+K263DkJK7OJeifh7FicKD9A1/IpGdKkyFpNmCkAADs=);
}
.mce-visualblocks pre {
padding-top: 10px;
border: 1px dashed #BBB;
margin-left: 3px;
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhFQAKAIABALu7uwAAACH5BAEAAAEALAAAAAAVAAoAAAIjjI+ZoN0cgDwSmnpz1NCueYERhnibZVKLNnbOq8IvKpJtVQAAOw==);
}
.mce-visualblocks figure {
padding-top: 10px;
border: 1px dashed #BBB;
margin: 0 0 1em 3px;
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhJAAKAIAAALu7u////yH5BAEAAAEALAAAAAAkAAoAAAI0jI+py+2fwAHUSFvD3RlvG4HIp4nX5JFSpnZUJ6LlrM52OE7uSWosBHScgkSZj7dDKnWAAgA7);
}
.mce-visualblocks hgroup {
padding-top: 10px;
border: 1px dashed #BBB;
margin: 0 0 1em 3px;
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhJwAKAIABALu7uwAAACH5BAEAAAEALAAAAAAnAAoAAAI3jI+pywYNI3uB0gpsRtt5fFnfNZaVSYJil4Wo03Hv6Z62uOCgiXH1kZIIJ8NiIxRrAZNMZAtQAAA7);
}
.mce-visualblocks aside {
padding-top: 10px;
border: 1px dashed #BBB;
margin: 0 0 1em 3px;
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhHgAKAIABAKqqqv///yH5BAEAAAEALAAAAAAeAAoAAAItjI+pG8APjZOTzgtqy7I3f1yehmQcFY4WKZbqByutmW4aHUd6vfcVbgudgpYCADs=);
}
.mce-visualblocks figcaption {
border: 1px dashed #BBB;
}
.mce-visualblocks ul {
padding-top: 10px;
border: 1px dashed #BBB;
margin: 0 0 1em 3px;
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhDQAKAIAAALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGuYnqUVSjvw26DzzXiqIDlVwAAOw==)
}
.mce-visualblocks ol {
padding-top: 10px;
border: 1px dashed #BBB;
margin: 0 0 1em 3px;
background: transparent no-repeat url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybH6HHt0qourxC6CvzXieHyeWQAAOw==);
}
================================================
FILE: public/js/tinymce/skins/lightgray/fonts/readme.md
================================================
Icons are generated and provided by the http://icomoon.io service.
================================================
FILE: public/js/tinymce/tinymce.setup.js
================================================
(function() {
$(document).ready(function() {
var language = $("html").attr("lang");
var basePath = $("#logo").attr("href");
if (language === "en-US") {
language = undefined;
}
tinymce.init({
"selector": ".wysiwyg-editor",
"language": language,
"plugins": "save image media link table charmap code",
"content_css": basePath + "/css/tinymce/default.min.css",
"toolbar": "save | undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image media table | charmap code",
"menubar": false,
"statusbar": false,
"relative_urls": false,
file_browser_callback : function(field_name, url, type, win) {
var w = window,
d = document,
e = d.documentElement,
g = d.getElementsByTagName("body")[0],
x = w.innerWidth || e.clientWidth || g.clientWidth,
y = w.innerHeight|| e.clientHeight|| g.clientHeight;
var cmsURL = basePath + "vendor/filemanager/index.html?&field_name=" + field_name + "&langCode=" + tinymce.settings.language;
if (type == "image") {
cmsURL = cmsURL + "&type=images";
}
tinyMCE.activeEditor.windowManager.open({
file : cmsURL,
title : "Filemanager",
width : x * 0.8,
height : y * 0.8,
resizable : "yes",
close_previous : "no"
});
}
});
});
})();
================================================
FILE: public/js/tinymce/tinymce.setup.light.js
================================================
(function() {
$(document).ready(function() {
var language = $("html").attr("lang");
var basePath = $("#logo").attr("href");
if (language === "en-US") {
language = undefined;
}
tinymce.init({
"selector": ".wysiwyg-editor",
"language": language,
"plugins": "image link",
"content_css": basePath + "css/tinymce/default.min.css",
"toolbar": "undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image",
"menubar": false,
"statusbar": false,
"relative_urls": false,
file_browser_callback : function(field_name, url, type, win) {
var w = window,
d = document,
e = d.documentElement,
g = d.getElementsByTagName("body")[0],
x = w.innerWidth || e.clientWidth || g.clientWidth,
y = w.innerHeight|| e.clientHeight|| g.clientHeight;
var cmsURL = basePath + "vendor/filemanager/index.html?&field_name=" + field_name + "&langCode=" + tinymce.settings.language;
if (type == "image") {
cmsURL = cmsURL + "&type=images";
}
tinyMCE.activeEditor.windowManager.open({
file : cmsURL,
title : "Filemanager",
width : x * 0.8,
height : y * 0.8,
resizable : "yes",
close_previous : "no"
});
}
});
});
})();
================================================
FILE: public/js/tinymce/tinymce.setup.medium.js
================================================
(function() {
$(document).ready(function() {
var language = $("html").attr("lang");
var basePath = $("#logo").attr("href");
if (language === "en-US") {
language = undefined;
}
tinymce.init({
"selector": ".wysiwyg-editor",
"language": language,
"plugins": "image media link table charmap code",
"content_css": basePath + "css/tinymce/default.min.css",
"toolbar": "undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image media table | charmap code",
"menubar": false,
"statusbar": false,
"relative_urls": false,
file_browser_callback : function(field_name, url, type, win) {
var w = window,
d = document,
e = d.documentElement,
g = d.getElementsByTagName("body")[0],
x = w.innerWidth || e.clientWidth || g.clientWidth,
y = w.innerHeight|| e.clientHeight|| g.clientHeight;
var cmsURL = basePath + "vendor/filemanager/index.html?&field_name=" + field_name + "&langCode=" + tinymce.settings.language;
if (type == "image") {
cmsURL = cmsURL + "&type=images";
}
tinyMCE.activeEditor.windowManager.open({
file : cmsURL,
title : "Filemanager",
width : x * 0.8,
height : y * 0.8,
resizable : "yes",
close_previous : "no"
});
}
});
});
})();
================================================
FILE: public/js-client/.gitignore
================================================
*
!.gitignore
================================================
FILE: public/misc/robots.txt
================================================
User-agent: *
Disallow:
================================================
FILE: public/misc-client/.gitignore
================================================
*
!.gitignore
================================================
FILE: public/setup.php
================================================
intl extension is required but not installed. '
. 'Please contact your web hosting provider to get this one fixed.');
}
/**
* We are using composer (getcomposer.org) to install and autoload the dependencies.
* Composer will create the entire vendor directory for us, including the autoloader.
*/
$autoloader = 'vendor/autoload.php';
if (! is_readable($autoloader)) {
$charon = 'module/Base/Charon.php';
if (! is_readable($charon)) {
exit('Base module not found');
}
/**
* Display an informative error page.
*/
require $charon;
Base\Charon::carry('application', 'installation', 1);
}
/**
* Load and prepare the autoloader.
*/
require $autoloader;
/**
* Initialize our PHP environment.
*/
$init = 'config/init.php';
if (! is_readable($init)) {
exit('Please rename config/init.php.dist to config/init.php and edit its options accordingly');
}
/**
* Initialize our application with the setup configuration file and run!
*/
Zend\Mvc\Application::init(require 'config/setup.php')->run();
================================================
FILE: src/Zend/Config/LICENSE.md
================================================
Copyright (c) 2005-2015, Zend Technologies USA, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
- Neither the name of Zend Technologies USA, Inc. nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================
FILE: src/Zend/Config/README.md
================================================
# zend-config
[](https://secure.travis-ci.org/zendframework/zend-config)
[](https://coveralls.io/r/zendframework/zend-config?branch=master)
`Zend\Config` is designed to simplify access to configuration data within
applications. It provides a nested object property-based user interface for
accessing this configuration data within application code. The configuration
data may come from a variety of media supporting hierarchical data storage.
- File issues at https://github.com/zendframework/zend-config/issues
- Documentation is at https://zendframework.github.io/zend-config/
================================================
FILE: src/Zend/Config/src/AbstractConfigFactory.php
================================================
canCreate($serviceLocator, $requestedName);
}
/**
* Determine if we can create a service (SM v3)
*
* @param ContainerInterface $container
* @param string $requestedName
* @return bool
*/
public function canCreate(ContainerInterface $container, $requestedName)
{
if (isset($this->configs[$requestedName])) {
return true;
}
if (! $container->has('Config')) {
return false;
}
$key = $this->match($requestedName);
if (null === $key) {
return false;
}
$config = $container->get('Config');
return isset($config[$key]);
}
/**
* Create service with name (SM v2)
*
* @param ServiceLocatorInterface $serviceLocator
* @param string $name
* @param string $requestedName
* @return string|mixed|array
*/
public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
{
return $this($serviceLocator, $requestedName);
}
/**
* Create service with name (SM v3)
*
* @param ContainerInterface $container
* @param string $requestedName
* @param array|null $options
* @return string|mixed|array
*/
public function __invoke(ContainerInterface $container, $requestedName, ?array $options = null)
{
if (isset($this->configs[$requestedName])) {
return $this->configs[$requestedName];
}
$key = $this->match($requestedName);
if (isset($this->configs[$key])) {
$this->configs[$requestedName] = $this->configs[$key];
return $this->configs[$key];
}
$config = $container->get('Config');
$this->configs[$requestedName] = $this->configs[$key] = $config[$key];
return $config[$key];
}
/**
* @param string $pattern
* @return self
* @throws Exception\InvalidArgumentException
*/
public function addPattern($pattern)
{
if (!is_string($pattern)) {
throw new Exception\InvalidArgumentException('pattern must be string');
}
$patterns = $this->getPatterns();
array_unshift($patterns, $pattern);
$this->setPatterns($patterns);
return $this;
}
/**
* @param array|Traversable $patterns
* @return self
* @throws Exception\InvalidArgumentException
*/
public function addPatterns($patterns)
{
if ($patterns instanceof Traversable) {
$patterns = iterator_to_array($patterns);
}
if (!is_array($patterns)) {
throw new Exception\InvalidArgumentException("patterns must be array or Traversable");
}
foreach ($patterns as $pattern) {
$this->addPattern($pattern);
}
return $this;
}
/**
* @param array|Traversable $patterns
* @return self
* @throws \InvalidArgumentException
*/
public function setPatterns($patterns)
{
if ($patterns instanceof Traversable) {
$patterns = iterator_to_array($patterns);
}
if (!is_array($patterns)) {
throw new \InvalidArgumentException("patterns must be array or Traversable");
}
$this->patterns = $patterns;
return $this;
}
/**
* @return array
*/
public function getPatterns()
{
if (null === $this->patterns) {
$this->setPatterns($this->defaultPatterns);
}
return $this->patterns;
}
/**
* @param string $requestedName
* @return null|string
*/
protected function match($requestedName)
{
foreach ($this->getPatterns() as $pattern) {
if (preg_match($pattern, $requestedName, $matches)) {
return $matches[1];
}
}
return;
}
}
================================================
FILE: src/Zend/Config/src/Config.php
================================================
allowModifications = (bool) $allowModifications;
foreach ($array as $key => $value) {
if (is_array($value)) {
$this->data[$key] = new static($value, $this->allowModifications);
} else {
$this->data[$key] = $value;
}
}
}
/**
* Retrieve a value and return $default if there is no element set.
*
* @param string $name
* @param mixed $default
* @return mixed
*/
public function get($name, $default = null)
{
if (array_key_exists($name, $this->data)) {
return $this->data[$name];
}
return $default;
}
/**
* Magic function so that $obj->value will work.
*
* @param string $name
* @return mixed
*/
public function __get($name)
{
return $this->get($name);
}
/**
* Set a value in the config.
*
* Only allow setting of a property if $allowModifications was set to true
* on construction. Otherwise, throw an exception.
*
* @param string $name
* @param mixed $value
* @return void
* @throws Exception\RuntimeException
*/
public function __set($name, $value)
{
if ($this->allowModifications) {
if (is_array($value)) {
$value = new static($value, true);
}
if (null === $name) {
$this->data[] = $value;
} else {
$this->data[$name] = $value;
}
} else {
throw new Exception\RuntimeException('Config is read only');
}
}
/**
* Deep clone of this instance to ensure that nested Zend\Configs are also
* cloned.
*
* @return void
*/
public function __clone()
{
$array = [];
foreach ($this->data as $key => $value) {
if ($value instanceof self) {
$array[$key] = clone $value;
} else {
$array[$key] = $value;
}
}
$this->data = $array;
}
/**
* Return an associative array of the stored data.
*
* @return array
*/
public function toArray()
{
$array = [];
$data = $this->data;
/** @var self $value */
foreach ($data as $key => $value) {
if ($value instanceof self) {
$array[$key] = $value->toArray();
} else {
$array[$key] = $value;
}
}
return $array;
}
/**
* isset() overloading
*
* @param string $name
* @return bool
*/
public function __isset($name)
{
return isset($this->data[$name]);
}
/**
* unset() overloading
*
* @param string $name
* @return void
* @throws Exception\InvalidArgumentException
*/
public function __unset($name)
{
if (!$this->allowModifications) {
throw new Exception\InvalidArgumentException('Config is read only');
} elseif (isset($this->data[$name])) {
unset($this->data[$name]);
$this->skipNextIteration = true;
}
}
/**
* count(): defined by Countable interface.
*
* @see Countable::count()
* @return int
*/
#[ReturnTypeWillChange] public function count()
{
return count($this->data);
}
/**
* current(): defined by Iterator interface.
*
* @see Iterator::current()
* @return mixed
*/
#[ReturnTypeWillChange] public function current()
{
$this->skipNextIteration = false;
return current($this->data);
}
/**
* key(): defined by Iterator interface.
*
* @see Iterator::key()
* @return mixed
*/
#[ReturnTypeWillChange] public function key()
{
return key($this->data);
}
/**
* next(): defined by Iterator interface.
*
* @see Iterator::next()
* @return void
*/
#[ReturnTypeWillChange] public function next()
{
if ($this->skipNextIteration) {
$this->skipNextIteration = false;
return;
}
next($this->data);
}
/**
* rewind(): defined by Iterator interface.
*
* @see Iterator::rewind()
* @return void
*/
#[ReturnTypeWillChange] public function rewind()
{
$this->skipNextIteration = false;
reset($this->data);
}
/**
* valid(): defined by Iterator interface.
*
* @see Iterator::valid()
* @return bool
*/
#[ReturnTypeWillChange] public function valid()
{
return ($this->key() !== null);
}
/**
* offsetExists(): defined by ArrayAccess interface.
*
* @see ArrayAccess::offsetExists()
* @param mixed $offset
* @return bool
*/
#[ReturnTypeWillChange] public function offsetExists($offset)
{
return $this->__isset($offset);
}
/**
* offsetGet(): defined by ArrayAccess interface.
*
* @see ArrayAccess::offsetGet()
* @param mixed $offset
* @return mixed
*/
#[ReturnTypeWillChange] public function offsetGet($offset)
{
return $this->__get($offset);
}
/**
* offsetSet(): defined by ArrayAccess interface.
*
* @see ArrayAccess::offsetSet()
* @param mixed $offset
* @param mixed $value
* @return void
*/
#[ReturnTypeWillChange] public function offsetSet($offset, $value)
{
$this->__set($offset, $value);
}
/**
* offsetUnset(): defined by ArrayAccess interface.
*
* @see ArrayAccess::offsetUnset()
* @param mixed $offset
* @return void
*/
#[ReturnTypeWillChange] public function offsetUnset($offset)
{
$this->__unset($offset);
}
/**
* Merge another Config with this one.
*
* For duplicate keys, the following will be performed:
* - Nested Configs will be recursively merged.
* - Items in $merge with INTEGER keys will be appended.
* - Items in $merge with STRING keys will overwrite current values.
*
* @param Config $merge
* @return Config
*/
public function merge(Config $merge)
{
/** @var Config $value */
foreach ($merge as $key => $value) {
if (array_key_exists($key, $this->data)) {
if (is_int($key)) {
$this->data[] = $value;
} elseif ($value instanceof self && $this->data[$key] instanceof self) {
$this->data[$key]->merge($value);
} else {
if ($value instanceof self) {
$this->data[$key] = new static($value->toArray(), $this->allowModifications);
} else {
$this->data[$key] = $value;
}
}
} else {
if ($value instanceof self) {
$this->data[$key] = new static($value->toArray(), $this->allowModifications);
} else {
$this->data[$key] = $value;
}
}
}
return $this;
}
/**
* Prevent any more modifications being made to this instance.
*
* Useful after merge() has been used to merge multiple Config objects
* into one object which should then not be modified again.
*
* @return void
*/
public function setReadOnly()
{
$this->allowModifications = false;
/** @var Config $value */
foreach ($this->data as $value) {
if ($value instanceof self) {
$value->setReadOnly();
}
}
}
/**
* Returns whether this Config object is read only or not.
*
* @return bool
*/
public function isReadOnly()
{
return !$this->allowModifications;
}
}
================================================
FILE: src/Zend/Config/src/Exception/ExceptionInterface.php
================================================
'ini',
'json' => 'json',
'xml' => 'xml',
'yaml' => 'yaml',
'properties' => 'javaproperties',
];
/**
* Register config file extensions for writing
* key is extension, value is writer instance or plugin name
*
* @var array
*/
protected static $writerExtensions = [
'php' => 'php',
'ini' => 'ini',
'json' => 'json',
'xml' => 'xml',
'yaml' => 'yaml',
];
/**
* Read a config from a file.
*
* @param string $filename
* @param bool $returnConfigObject
* @param bool $useIncludePath
* @return array|Config
* @throws Exception\InvalidArgumentException
* @throws Exception\RuntimeException
*/
public static function fromFile($filename, $returnConfigObject = false, $useIncludePath = false)
{
$filepath = $filename;
if (!file_exists($filename)) {
if (!$useIncludePath) {
throw new Exception\RuntimeException(sprintf(
'Filename "%s" cannot be found relative to the working directory',
$filename
));
}
$fromIncludePath = stream_resolve_include_path($filename);
if (!$fromIncludePath) {
throw new Exception\RuntimeException(sprintf(
'Filename "%s" cannot be found relative to the working directory or the include_path ("%s")',
$filename,
get_include_path()
));
}
$filepath = $fromIncludePath;
}
$pathinfo = pathinfo($filepath);
if (!isset($pathinfo['extension'])) {
throw new Exception\RuntimeException(sprintf(
'Filename "%s" is missing an extension and cannot be auto-detected',
$filename
));
}
$extension = strtolower($pathinfo['extension']);
if ($extension === 'php') {
if (!is_file($filepath) || !is_readable($filepath)) {
throw new Exception\RuntimeException(sprintf(
"File '%s' doesn't exist or not readable",
$filename
));
}
$config = include $filepath;
} elseif (isset(static::$extensions[$extension])) {
$reader = static::$extensions[$extension];
if (!$reader instanceof Reader\ReaderInterface) {
$reader = static::getReaderPluginManager()->get($reader);
static::$extensions[$extension] = $reader;
}
/* @var Reader\ReaderInterface $reader */
$config = $reader->fromFile($filepath);
} else {
throw new Exception\RuntimeException(sprintf(
'Unsupported config file extension: .%s',
$pathinfo['extension']
));
}
return ($returnConfigObject) ? new Config($config) : $config;
}
/**
* Read configuration from multiple files and merge them.
*
* @param array $files
* @param bool $returnConfigObject
* @param bool $useIncludePath
* @return array|Config
*/
public static function fromFiles(array $files, $returnConfigObject = false, $useIncludePath = false)
{
$config = [];
foreach ($files as $file) {
$config = ArrayUtils::merge($config, static::fromFile($file, false, $useIncludePath));
}
return ($returnConfigObject) ? new Config($config) : $config;
}
/**
* Writes a config to a file
*
* @param string $filename
* @param array|Config $config
* @return bool TRUE on success | FALSE on failure
* @throws Exception\RuntimeException
* @throws Exception\InvalidArgumentException
*/
public static function toFile($filename, $config)
{
if ((is_object($config) && !($config instanceof Config))
|| (!is_object($config) && !is_array($config))
) {
throw new Exception\InvalidArgumentException(
__METHOD__." \$config should be an array or instance of Zend\\Config\\Config"
);
}
$extension = substr(strrchr($filename, '.'), 1);
$directory = dirname($filename);
if (!is_dir($directory)) {
throw new Exception\RuntimeException(
"Directory '{$directory}' does not exists!"
);
}
if (!is_writable($directory)) {
throw new Exception\RuntimeException(
"Cannot write in directory '{$directory}'"
);
}
if (!isset(static::$writerExtensions[$extension])) {
throw new Exception\RuntimeException(
"Unsupported config file extension: '.{$extension}' for writing."
);
}
$writer = static::$writerExtensions[$extension];
if (($writer instanceof Writer\AbstractWriter) === false) {
$writer = self::getWriterPluginManager()->get($writer);
static::$writerExtensions[$extension] = $writer;
}
if (is_object($config)) {
$config = $config->toArray();
}
$content = $writer->processConfig($config);
return file_put_contents($filename, $content) !== false;
}
/**
* Set reader plugin manager
*
* @param ReaderPluginManager $readers
* @return void
*/
public static function setReaderPluginManager(ReaderPluginManager $readers)
{
static::$readers = $readers;
}
/**
* Get the reader plugin manager
*
* @return ReaderPluginManager
*/
public static function getReaderPluginManager()
{
if (static::$readers === null) {
static::$readers = new ReaderPluginManager(new ServiceManager());
}
return static::$readers;
}
/**
* Set writer plugin manager
*
* @param WriterPluginManager $writers
* @return void
*/
public static function setWriterPluginManager(WriterPluginManager $writers)
{
static::$writers = $writers;
}
/**
* Get the writer plugin manager
*
* @return WriterPluginManager
*/
public static function getWriterPluginManager()
{
if (static::$writers === null) {
static::$writers = new WriterPluginManager(new ServiceManager());
}
return static::$writers;
}
/**
* Set config reader for file extension
*
* @param string $extension
* @param string|Reader\ReaderInterface $reader
* @throws Exception\InvalidArgumentException
* @return void
*/
public static function registerReader($extension, $reader)
{
$extension = strtolower($extension);
if (!is_string($reader) && !$reader instanceof Reader\ReaderInterface) {
throw new Exception\InvalidArgumentException(sprintf(
'Reader should be plugin name, class name or ' .
'instance of %s\Reader\ReaderInterface; received "%s"',
__NAMESPACE__,
(is_object($reader) ? get_class($reader) : gettype($reader))
));
}
static::$extensions[$extension] = $reader;
}
/**
* Set config writer for file extension
*
* @param string $extension
* @param string|Writer\AbstractWriter $writer
* @throws Exception\InvalidArgumentException
* @return void
*/
public static function registerWriter($extension, $writer)
{
$extension = strtolower($extension);
if (!is_string($writer) && !$writer instanceof Writer\AbstractWriter) {
throw new Exception\InvalidArgumentException(sprintf(
'Writer should be plugin name, class name or ' .
'instance of %s\Writer\AbstractWriter; received "%s"',
__NAMESPACE__,
(is_object($writer) ? get_class($writer) : gettype($writer))
));
}
static::$writerExtensions[$extension] = $writer;
}
}
================================================
FILE: src/Zend/Config/src/Processor/Constant.php
================================================
setUserOnly($userOnly);
$this->setPrefix($prefix);
$this->setSuffix($suffix);
$this->loadConstants();
}
/**
* @return bool
*/
public function getUserOnly()
{
return $this->userOnly;
}
/**
* Should we use only user-defined constants?
*
* @param bool $userOnly
* @return Constant
*/
public function setUserOnly($userOnly)
{
$this->userOnly = (bool) $userOnly;
return $this;
}
/**
* Load all currently defined constants into parser.
*
* @return void
*/
public function loadConstants()
{
if ($this->userOnly) {
$constants = get_defined_constants(true);
$constants = $constants['user'] ?? [];
$this->setTokens($constants);
} else {
$this->setTokens(get_defined_constants());
}
}
/**
* Get current token registry.
* @return array
*/
public function getTokens()
{
return $this->tokens;
}
}
================================================
FILE: src/Zend/Config/src/Processor/Filter.php
================================================
setFilter($filter);
}
/**
* @param ZendFilter $filter
* @return Filter
*/
public function setFilter(ZendFilter $filter)
{
$this->filter = $filter;
return $this;
}
/**
* @return ZendFilter
*/
public function getFilter()
{
return $this->filter;
}
/**
* Process
*
* @param Config $config
* @return Config
* @throws Exception\InvalidArgumentException
*/
public function process(Config $config)
{
if ($config->isReadOnly()) {
throw new Exception\InvalidArgumentException('Cannot process config because it is read-only');
}
/**
* Walk through config and replace values
*/
foreach ($config as $key => $val) {
if ($val instanceof Config) {
$this->process($val);
} else {
$config->$key = $this->filter->filter($val);
}
}
return $config;
}
/**
* Process a single value
*
* @param mixed $value
* @return mixed
*/
public function processValue($value)
{
return $this->filter->filter($value);
}
}
================================================
FILE: src/Zend/Config/src/Processor/ProcessorInterface.php
================================================
isReadOnly()) {
throw new Exception\InvalidArgumentException('Cannot process config because it is read-only');
}
foreach ($this as $parser) {
/** @var $parser ProcessorInterface */
$parser->process($config);
}
}
/**
* Process a single value
*
* @param mixed $value
* @return mixed
*/
public function processValue($value)
{
foreach ($this as $parser) {
/** @var $parser ProcessorInterface */
$value = $parser->processValue($value);
}
return $value;
}
}
================================================
FILE: src/Zend/Config/src/Processor/Token.php
================================================
value
* to replace it with
* @param string $prefix
* @param string $suffix
* @return Token
*/
public function __construct($tokens = [], $prefix = '', $suffix = '')
{
$this->setTokens($tokens);
$this->setPrefix($prefix);
$this->setSuffix($suffix);
}
/**
* @param string $prefix
* @return Token
*/
public function setPrefix($prefix)
{
// reset map
$this->map = null;
$this->prefix = $prefix;
return $this;
}
/**
* @return string
*/
public function getPrefix()
{
return $this->prefix;
}
/**
* @param string $suffix
* @return Token
*/
public function setSuffix($suffix)
{
// reset map
$this->map = null;
$this->suffix = $suffix;
return $this;
}
/**
* @return string
*/
public function getSuffix()
{
return $this->suffix;
}
/**
* Set token registry.
*
* @param array|Config|Traversable $tokens Associative array of TOKEN => value
* to replace it with
* @return Token
* @throws Exception\InvalidArgumentException
*/
public function setTokens($tokens)
{
if (is_array($tokens)) {
$this->tokens = $tokens;
} elseif ($tokens instanceof Config) {
$this->tokens = $tokens->toArray();
} elseif ($tokens instanceof Traversable) {
$this->tokens = [];
foreach ($tokens as $key => $val) {
$this->tokens[$key] = $val;
}
} else {
throw new Exception\InvalidArgumentException('Cannot use ' . gettype($tokens) . ' as token registry.');
}
// reset map
$this->map = null;
return $this;
}
/**
* Get current token registry.
*
* @return array
*/
public function getTokens()
{
return $this->tokens;
}
/**
* Add new token.
*
* @param string $token
* @param mixed $value
* @return Token
* @throws Exception\InvalidArgumentException
*/
public function addToken($token, $value)
{
if (!is_scalar($token)) {
throw new Exception\InvalidArgumentException('Cannot use ' . gettype($token) . ' as token name.');
}
$this->tokens[$token] = $value;
// reset map
$this->map = null;
return $this;
}
/**
* Add new token.
*
* @param string $token
* @param mixed $value
* @return Token
*/
public function setToken($token, $value)
{
return $this->addToken($token, $value);
}
/**
* Build replacement map
*
* @return array
*/
protected function buildMap()
{
if (null === $this->map) {
if (!$this->suffix && !$this->prefix) {
$this->map = $this->tokens;
} else {
$this->map = [];
foreach ($this->tokens as $token => $value) {
$this->map[$this->prefix . $token . $this->suffix] = $value;
}
}
foreach (array_keys($this->map) as $key) {
if (empty($key)) {
unset($this->map[$key]);
}
}
}
return $this->map;
}
/**
* Process
*
* @param Config $config
* @return Config
* @throws Exception\InvalidArgumentException
*/
public function process(Config $config)
{
return $this->doProcess($config, $this->buildMap());
}
/**
* Process a single value
*
* @param $value
* @return mixed
*/
public function processValue($value)
{
return $this->doProcess($value, $this->buildMap());
}
/**
* Applies replacement map to the given value by modifying the value itself
*
* @param mixed $value
* @param array $replacements
*
* @return mixed
*
* @throws Exception\InvalidArgumentException if the provided value is a read-only {@see Config}
*/
private function doProcess($value, array $replacements)
{
if ($value instanceof Config) {
if ($value->isReadOnly()) {
throw new Exception\InvalidArgumentException('Cannot process config because it is read-only');
}
foreach ($value as $key => $val) {
$value->$key = $this->doProcess($val, $replacements);
}
return $value;
}
if ($value instanceof Traversable || is_array($value)) {
foreach ($value as & $val) {
$val = $this->doProcess($val, $replacements);
}
return $value;
}
if (!is_string($value) && (is_bool($value) || is_numeric($value))) {
$stringVal = (string) $value;
$changedVal = strtr($stringVal, $this->map);
// replace the value only if a string replacement occurred
if ($changedVal !== $stringVal) {
return $changedVal;
}
return $value;
}
return strtr((string) $value, $this->map);
}
}
================================================
FILE: src/Zend/Config/src/Processor/Translator.php
================================================
setTranslator($translator);
$this->setTextDomain($textDomain);
$this->setLocale($locale);
}
/**
* @param ZendTranslator $translator
* @return Translator
*/
public function setTranslator(ZendTranslator $translator)
{
$this->translator = $translator;
return $this;
}
/**
* @return ZendTranslator
*/
public function getTranslator()
{
return $this->translator;
}
/**
* @param string|null $locale
* @return Translator
*/
public function setLocale($locale)
{
$this->locale = $locale;
return $this;
}
/**
* @return string|null
*/
public function getLocale()
{
return $this->locale;
}
/**
* @param string $textDomain
* @return Translator
*/
public function setTextDomain($textDomain)
{
$this->textDomain = $textDomain;
return $this;
}
/**
* @return string
*/
public function getTextDomain()
{
return $this->textDomain;
}
/**
* Process
*
* @param Config $config
* @return Config
* @throws Exception\InvalidArgumentException
*/
public function process(Config $config)
{
if ($config->isReadOnly()) {
throw new Exception\InvalidArgumentException('Cannot process config because it is read-only');
}
/**
* Walk through config and replace values
*/
foreach ($config as $key => $val) {
if ($val instanceof Config) {
$this->process($val);
} else {
$config->{$key} = $this->translator->translate($val, $this->textDomain, $this->locale);
}
}
return $config;
}
/**
* Process a single value
*
* @param $value
* @return string
*/
public function processValue($value)
{
return $this->translator->translate($value, $this->textDomain, $this->locale);
}
}
================================================
FILE: src/Zend/Config/src/Reader/Ini.php
================================================
nestSeparator = $separator;
return $this;
}
/**
* Get nest separator.
*
* @return string
*/
public function getNestSeparator()
{
return $this->nestSeparator;
}
/**
* fromFile(): defined by Reader interface.
*
* @see ReaderInterface::fromFile()
* @param string $filename
* @return array
* @throws Exception\RuntimeException
*/
public function fromFile($filename)
{
if (!is_file($filename) || !is_readable($filename)) {
throw new Exception\RuntimeException(sprintf(
"File '%s' doesn't exist or not readable",
$filename
));
}
$this->directory = dirname($filename);
set_error_handler(
function ($error, $message = '') use ($filename) {
throw new Exception\RuntimeException(
sprintf('Error reading INI file "%s": %s', $filename, $message),
$error
);
},
E_WARNING
);
$ini = parse_ini_file($filename, true);
restore_error_handler();
return $this->process($ini);
}
/**
* fromString(): defined by Reader interface.
*
* @param string $string
* @return array|bool
* @throws Exception\RuntimeException
*/
public function fromString($string)
{
if (empty($string)) {
return [];
}
$this->directory = null;
set_error_handler(
function ($error, $message = '') {
throw new Exception\RuntimeException(
sprintf('Error reading INI string: %s', $message),
$error
);
},
E_WARNING
);
$ini = parse_ini_string($string, true);
restore_error_handler();
return $this->process($ini);
}
/**
* Process data from the parsed ini file.
*
* @param array $data
* @return array
*/
protected function process(array $data)
{
$config = [];
foreach ($data as $section => $value) {
if (is_array($value)) {
if (str_contains($section, $this->nestSeparator)) {
$sections = explode($this->nestSeparator, $section);
$config = array_merge_recursive($config, $this->buildNestedSection($sections, $value));
} else {
$config[$section] = $this->processSection($value);
}
} else {
$this->processKey($section, $value, $config);
}
}
return $config;
}
/**
* Process a nested section
*
* @param array $sections
* @param mixed $value
* @return array
*/
private function buildNestedSection($sections, $value)
{
if (count($sections) == 0) {
return $this->processSection($value);
}
$nestedSection = [];
$first = array_shift($sections);
$nestedSection[$first] = $this->buildNestedSection($sections, $value);
return $nestedSection;
}
/**
* Process a section.
*
* @param array $section
* @return array
*/
protected function processSection(array $section)
{
$config = [];
foreach ($section as $key => $value) {
$this->processKey($key, $value, $config);
}
return $config;
}
/**
* Process a key.
*
* @param string $key
* @param string $value
* @param array $config
* @return array
* @throws Exception\RuntimeException
*/
protected function processKey($key, $value, array &$config)
{
if (str_contains($key, $this->nestSeparator)) {
$pieces = explode($this->nestSeparator, $key, 2);
if (!strlen($pieces[0]) || !strlen($pieces[1])) {
throw new Exception\RuntimeException(sprintf('Invalid key "%s"', $key));
} elseif (!isset($config[$pieces[0]])) {
if ($pieces[0] === '0' && !empty($config)) {
$config = [$pieces[0] => $config];
} else {
$config[$pieces[0]] = [];
}
} elseif (!is_array($config[$pieces[0]])) {
throw new Exception\RuntimeException(
sprintf('Cannot create sub-key for "%s", as key already exists', $pieces[0])
);
}
$this->processKey($pieces[1], $value, $config[$pieces[0]]);
} else {
if ($key === '@include') {
if ($this->directory === null) {
throw new Exception\RuntimeException('Cannot process @include statement for a string config');
}
$reader = clone $this;
$include = $reader->fromFile($this->directory . '/' . $value);
$config = array_replace_recursive($config, $include);
} else {
$config[$key] = $value;
}
}
}
}
================================================
FILE: src/Zend/Config/src/Reader/JavaProperties.php
================================================
directory = dirname($filename);
$config = $this->parse(file_get_contents($filename));
return $this->process($config);
}
/**
* fromString(): defined by Reader interface.
*
* @see ReaderInterface::fromString()
* @param string $string
* @return array
* @throws Exception\RuntimeException if an @include key is found
*/
public function fromString($string)
{
if (empty($string)) {
return [];
}
$this->directory = null;
$config = $this->parse($string);
return $this->process($config);
}
/**
* Process the array for @include
*
* @param array $data
* @return array
* @throws Exception\RuntimeException if an @include key is found
*/
protected function process(array $data)
{
foreach ($data as $key => $value) {
if (trim($key) === '@include') {
if ($this->directory === null) {
throw new Exception\RuntimeException('Cannot process @include statement for a string');
}
$reader = clone $this;
unset($data[$key]);
$data = array_replace_recursive($data, $reader->fromFile($this->directory . '/' . $value));
}
}
return $data;
}
/**
* Parse Java-style properties string
*
* @todo Support use of the equals sign "key=value" as key-value delimiter
* @todo Ignore whitespace that precedes text past the first line of multiline values
*
* @param string $string
* @return array
*/
protected function parse($string)
{
$result = [];
$lines = explode("\n", $string);
$key = "";
$isWaitingOtherLine = false;
foreach ($lines as $i => $line) {
// Ignore empty lines and commented lines
if (empty($line)
|| (!$isWaitingOtherLine && str_starts_with($line, "#"))
|| (!$isWaitingOtherLine && str_starts_with($line, "!"))) {
continue;
}
// Add a new key-value pair or append value to a previous pair
if (!$isWaitingOtherLine) {
$key = substr($line, 0, strpos($line, ':'));
$value = substr($line, strpos($line, ':') + 1, strlen($line));
} else {
$value = $line;
}
// Check if ends with single '\' (indicating another line is expected)
if (strrpos($value, "\\") === strlen($value) - strlen("\\")) {
$value = substr($value, 0, strlen($value) - 1);
$isWaitingOtherLine = true;
} else {
$isWaitingOtherLine = false;
}
$result[$key] = stripslashes($value);
unset($lines[$i]);
}
return $result;
}
}
================================================
FILE: src/Zend/Config/src/Reader/Json.php
================================================
directory = dirname($filename);
try {
$config = JsonFormat::decode(file_get_contents($filename), JsonFormat::TYPE_ARRAY);
} catch (JsonException\RuntimeException $e) {
throw new Exception\RuntimeException($e->getMessage());
}
return $this->process($config);
}
/**
* fromString(): defined by Reader interface.
*
* @see ReaderInterface::fromString()
* @param string $string
* @return array|bool
* @throws Exception\RuntimeException
*/
public function fromString($string)
{
if (empty($string)) {
return [];
}
$this->directory = null;
try {
$config = JsonFormat::decode($string, JsonFormat::TYPE_ARRAY);
} catch (JsonException\RuntimeException $e) {
throw new Exception\RuntimeException($e->getMessage());
}
return $this->process($config);
}
/**
* Process the array for @include
*
* @param array $data
* @return array
* @throws Exception\RuntimeException
*/
protected function process(array $data)
{
foreach ($data as $key => $value) {
if (is_array($value)) {
$data[$key] = $this->process($value);
}
if (trim($key) === '@include') {
if ($this->directory === null) {
throw new Exception\RuntimeException('Cannot process @include statement for a JSON string');
}
$reader = clone $this;
unset($data[$key]);
$data = array_replace_recursive($data, $reader->fromFile($this->directory . '/' . $value));
}
}
return $data;
}
}
================================================
FILE: src/Zend/Config/src/Reader/ReaderInterface.php
================================================
reader = new XMLReader();
$this->reader->open($filename, null, LIBXML_XINCLUDE);
$this->directory = dirname($filename);
set_error_handler(
function ($error, $message = '') use ($filename) {
throw new Exception\RuntimeException(
sprintf('Error reading XML file "%s": %s', $filename, $message),
$error
);
},
E_WARNING
);
$return = $this->process();
restore_error_handler();
$this->reader->close();
return $return;
}
/**
* fromString(): defined by Reader interface.
*
* @see ReaderInterface::fromString()
* @param string $string
* @return array|bool
* @throws Exception\RuntimeException
*/
public function fromString($string)
{
if (empty($string)) {
return [];
}
$this->reader = new XMLReader();
$this->reader->xml($string, null, LIBXML_XINCLUDE);
$this->directory = null;
set_error_handler(
function ($error, $message = '') {
throw new Exception\RuntimeException(
sprintf('Error reading XML string: %s', $message),
$error
);
},
E_WARNING
);
$return = $this->process();
restore_error_handler();
$this->reader->close();
return $return;
}
/**
* Process data from the created XMLReader.
*
* @return array
*/
protected function process()
{
return $this->processNextElement();
}
/**
* Process the next inner element.
*
* @return mixed
*/
protected function processNextElement()
{
$children = [];
$text = '';
while ($this->reader->read()) {
if ($this->reader->nodeType === XMLReader::ELEMENT) {
if ($this->reader->depth === 0) {
return $this->processNextElement();
}
$attributes = $this->getAttributes();
$name = $this->reader->name;
if ($this->reader->isEmptyElement) {
$child = [];
} else {
$child = $this->processNextElement();
}
if ($attributes) {
if (is_string($child)) {
$child = ['_' => $child];
}
if (! is_array($child)) {
$child = [];
}
$child = array_merge($child, $attributes);
}
if (isset($children[$name])) {
if (!is_array($children[$name]) || !array_key_exists(0, $children[$name])) {
$children[$name] = [$children[$name]];
}
$children[$name][] = $child;
} else {
$children[$name] = $child;
}
} elseif ($this->reader->nodeType === XMLReader::END_ELEMENT) {
break;
} elseif (in_array($this->reader->nodeType, $this->textNodes)) {
$text .= $this->reader->value;
}
}
return $children ?: $text;
}
/**
* Get all attributes on the current node.
*
* @return array
*/
protected function getAttributes()
{
$attributes = [];
if ($this->reader->hasAttributes) {
while ($this->reader->moveToNextAttribute()) {
$attributes[$this->reader->localName] = $this->reader->value;
}
$this->reader->moveToElement();
}
return $attributes;
}
}
================================================
FILE: src/Zend/Config/src/Reader/Yaml.php
================================================
setYamlDecoder($yamlDecoder);
} else {
if (function_exists('yaml_parse')) {
$this->setYamlDecoder('yaml_parse');
}
}
}
/**
* Set callback for decoding YAML
*
* @param string|callable $yamlDecoder the decoder to set
* @return Yaml
* @throws Exception\RuntimeException
*/
public function setYamlDecoder($yamlDecoder)
{
if (!is_callable($yamlDecoder)) {
throw new Exception\RuntimeException(
'Invalid parameter to setYamlDecoder() - must be callable'
);
}
$this->yamlDecoder = $yamlDecoder;
return $this;
}
/**
* Get callback for decoding YAML
*
* @return callable
*/
public function getYamlDecoder()
{
return $this->yamlDecoder;
}
/**
* fromFile(): defined by Reader interface.
*
* @see ReaderInterface::fromFile()
* @param string $filename
* @return array
* @throws Exception\RuntimeException
*/
public function fromFile($filename)
{
if (!is_file($filename) || !is_readable($filename)) {
throw new Exception\RuntimeException(sprintf(
"File '%s' doesn't exist or not readable",
$filename
));
}
if (null === $this->getYamlDecoder()) {
throw new Exception\RuntimeException("You didn't specify a Yaml callback decoder");
}
$this->directory = dirname($filename);
$config = call_user_func($this->getYamlDecoder(), file_get_contents($filename));
if (null === $config) {
throw new Exception\RuntimeException("Error parsing YAML data");
}
return $this->process($config);
}
/**
* fromString(): defined by Reader interface.
*
* @see ReaderInterface::fromString()
* @param string $string
* @return array|bool
* @throws Exception\RuntimeException
*/
public function fromString($string)
{
if (null === $this->getYamlDecoder()) {
throw new Exception\RuntimeException("You didn't specify a Yaml callback decoder");
}
if (empty($string)) {
return [];
}
$this->directory = null;
$config = call_user_func($this->getYamlDecoder(), $string);
if (null === $config) {
throw new Exception\RuntimeException("Error parsing YAML data");
}
return $this->process($config);
}
/**
* Process the array for @include
*
* @param array $data
* @return array
* @throws Exception\RuntimeException
*/
protected function process(array $data)
{
foreach ($data as $key => $value) {
if (is_array($value)) {
$data[$key] = $this->process($value);
}
if (trim($key) === '@include') {
if ($this->directory === null) {
throw new Exception\RuntimeException('Cannot process @include statement for a json string');
}
$reader = clone $this;
unset($data[$key]);
$data = array_replace_recursive($data, $reader->fromFile($this->directory . '/' . $value));
}
}
return $data;
}
}
================================================
FILE: src/Zend/Config/src/ReaderPluginManager.php
================================================
Reader\Ini::class,
'Ini' => Reader\Ini::class,
'json' => Reader\Json::class,
'Json' => Reader\Json::class,
'xml' => Reader\Xml::class,
'Xml' => Reader\Xml::class,
'yaml' => Reader\Yaml::class,
'Yaml' => Reader\Yaml::class,
'javaproperties' => Reader\JavaProperties::class,
'javaProperties' => Reader\JavaProperties::class,
'JavaProperties' => Reader\JavaProperties::class,
];
protected $factories = [
Reader\Ini::class => InvokableFactory::class,
Reader\Json::class => InvokableFactory::class,
Reader\Xml::class => InvokableFactory::class,
Reader\Yaml::class => InvokableFactory::class,
Reader\JavaProperties::class => InvokableFactory::class,
// Legacy (v2) due to alias resolution; canonical form of resolved
// alias is used to look up the factory, while the non-normalized
// resolved alias is used as the requested name passed to the factory.
'zendconfigreaderini' => InvokableFactory::class,
'zendconfigreaderjson' => InvokableFactory::class,
'zendconfigreaderxml' => InvokableFactory::class,
'zendconfigreaderyaml' => InvokableFactory::class,
'zendconfigreaderjavaproperties' => InvokableFactory::class,
];
/**
* Validate the plugin is of the expected type (v3).
*
* Validates against `$instanceOf`.
*
* @param mixed $instance
* @throws InvalidServiceException
*/
public function validate($instance)
{
if (! $instance instanceof $this->instanceOf) {
throw new InvalidServiceException(sprintf(
'%s can only create instances of %s; %s is invalid',
get_class($this),
$this->instanceOf,
(is_object($instance) ? get_class($instance) : gettype($instance))
));
}
}
/**
* Validate the plugin is of the expected type (v2).
*
* Proxies to `validate()`.
*
* @param mixed $instance
* @throws Exception\InvalidArgumentException
*/
public function validatePlugin($instance)
{
try {
$this->validate($instance);
} catch (InvalidServiceException $e) {
throw new Exception\InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
}
public function __construct(ContainerInterface $container, array $config = [])
{
$config = array_merge_recursive(['aliases' => $this->aliases], $config);
parent::__construct($container, $config);
}
}
================================================
FILE: src/Zend/Config/src/Writer/AbstractWriter.php
================================================
toString($config), $flags);
} catch (\Exception $e) {
restore_error_handler();
throw $e;
}
restore_error_handler();
}
/**
* toString(): defined by Writer interface.
*
* @see WriterInterface::toString()
* @param mixed $config
* @return string
* @throws Exception\InvalidArgumentException
*/
public function toString($config)
{
if ($config instanceof Traversable) {
$config = ArrayUtils::iteratorToArray($config);
} elseif (!is_array($config)) {
throw new Exception\InvalidArgumentException(__METHOD__ . ' expects an array or Traversable config');
}
return $this->processConfig($config);
}
/**
* @param array $config
* @return string
*/
abstract protected function processConfig(array $config);
}
================================================
FILE: src/Zend/Config/src/Writer/Ini.php
================================================
nestSeparator = $separator;
return $this;
}
/**
* Get nest separator.
*
* @return string
*/
public function getNestSeparator()
{
return $this->nestSeparator;
}
/**
* Set if rendering should occur without sections or not.
*
* If set to true, the INI file is rendered without sections completely
* into the global namespace of the INI file.
*
* @param bool $withoutSections
* @return Ini
*/
public function setRenderWithoutSectionsFlags($withoutSections)
{
$this->renderWithoutSections = (bool) $withoutSections;
return $this;
}
/**
* Return whether the writer should render without sections.
*
* @return bool
*/
public function shouldRenderWithoutSections()
{
return $this->renderWithoutSections;
}
/**
* processConfig(): defined by AbstractWriter.
*
* @param array $config
* @return string
*/
public function processConfig(array $config)
{
$iniString = '';
if ($this->shouldRenderWithoutSections()) {
$iniString .= $this->addBranch($config);
} else {
$config = $this->sortRootElements($config);
foreach ($config as $sectionName => $data) {
if (!is_array($data)) {
$iniString .= $sectionName
. ' = '
. $this->prepareValue($data)
. "\n";
} else {
$iniString .= '[' . $sectionName . ']' . "\n"
. $this->addBranch($data)
. "\n";
}
}
}
return $iniString;
}
/**
* Add a branch to an INI string recursively.
*
* @param array $config
* @param array $parents
* @return string
*/
protected function addBranch(array $config, $parents = [])
{
$iniString = '';
foreach ($config as $key => $value) {
$group = array_merge($parents, [$key]);
if (is_array($value)) {
$iniString .= $this->addBranch($value, $group);
} else {
$iniString .= implode($this->nestSeparator, $group)
. ' = '
. $this->prepareValue($value)
. "\n";
}
}
return $iniString;
}
/**
* Prepare a value for INI.
*
* @param mixed $value
* @return string
* @throws Exception\RuntimeException
*/
protected function prepareValue($value)
{
if (is_int($value) || is_float($value)) {
return $value;
} elseif (is_bool($value)) {
return ($value ? 'true' : 'false');
} elseif (! str_contains($value, '"')) {
return '"' . $value . '"';
} else {
throw new Exception\RuntimeException('Value can not contain double quotes');
}
}
/**
* Root elements that are not assigned to any section needs to be on the
* top of config.
*
* @param array $config
* @return array
*/
protected function sortRootElements(array $config)
{
$sections = [];
// Remove sections from config array.
foreach ($config as $key => $value) {
if (is_array($value)) {
$sections[$key] = $value;
unset($config[$key]);
}
}
// Read sections to the end.
foreach ($sections as $key => $value) {
$config[$key] = $value;
}
return $config;
}
}
================================================
FILE: src/Zend/Config/src/Writer/Json.php
================================================
$this->useBracketArraySyntax ? '[' : 'array(',
'close' => $this->useBracketArraySyntax ? ']' : ')'
];
return "processIndented($config, $arraySyntax) .
$arraySyntax['close'] . ";\n";
}
/**
* Sets whether or not to use the PHP 5.4+ "[]" array syntax.
*
* @param bool $value
* @return self
*/
public function setUseBracketArraySyntax($value)
{
$this->useBracketArraySyntax = $value;
return $this;
}
/**
* Sets whether or not to render resolvable FQN strings as scalars, using PHP 5.5+ class-keyword
*
* @param boolean $value
* @return self
*/
public function setUseClassNameScalars($value)
{
$this->useClassNameScalars = $value;
return $this;
}
/**
* @return boolean
*/
public function getUseClassNameScalars()
{
return $this->useClassNameScalars;
}
/**
* toFile(): defined by Writer interface.
*
* @see WriterInterface::toFile()
* @param string $filename
* @param mixed $config
* @param bool $exclusiveLock
* @return void
* @throws Exception\InvalidArgumentException
* @throws Exception\RuntimeException
*/
public function toFile($filename, $config, $exclusiveLock = true)
{
if (empty($filename)) {
throw new Exception\InvalidArgumentException('No file name specified');
}
$flags = 0;
if ($exclusiveLock) {
$flags |= LOCK_EX;
}
set_error_handler(
function ($error, $message = '') use ($filename) {
throw new Exception\RuntimeException(
sprintf('Error writing to "%s": %s', $filename, $message),
$error
);
},
E_WARNING
);
try {
// for Windows, paths are escaped.
$dirname = str_replace('\\', '\\\\', dirname($filename));
$string = $this->toString($config);
$string = str_replace("'" . $dirname, "__DIR__ . '", $string);
file_put_contents($filename, $string, $flags);
} catch (\Exception $e) {
restore_error_handler();
throw $e;
}
restore_error_handler();
}
/**
* Recursively processes a PHP config array structure into a readable format.
*
* @param array $config
* @param array $arraySyntax
* @param int $indentLevel
* @return string
*/
protected function processIndented(array $config, array $arraySyntax, &$indentLevel = 1)
{
$arrayString = "";
foreach ($config as $key => $value) {
$arrayString .= str_repeat(self::INDENT_STRING, $indentLevel);
$arrayString .= (is_int($key) ? $key : $this->processStringKey($key)) . ' => ';
if (is_array($value)) {
if ($value === []) {
$arrayString .= $arraySyntax['open'] . $arraySyntax['close'] . ",\n";
} else {
$indentLevel++;
$arrayString .= $arraySyntax['open'] . "\n"
. $this->processIndented($value, $arraySyntax, $indentLevel)
. str_repeat(self::INDENT_STRING, --$indentLevel) . $arraySyntax['close'] . ",\n";
}
} elseif (is_object($value)) {
$arrayString .= var_export($value, true) . ",\n";
} elseif (is_string($value)) {
$arrayString .= $this->processStringValue($value) . ",\n";
} elseif (is_bool($value)) {
$arrayString .= ($value ? 'true' : 'false') . ",\n";
} elseif ($value === null) {
$arrayString .= "null,\n";
} else {
$arrayString .= $value . ",\n";
}
}
return $arrayString;
}
/**
* Process a string configuration value
*
* @param string $value
* @return string
*/
protected function processStringValue($value)
{
if ($this->useClassNameScalars && false !== ($fqnValue = $this->fqnStringToClassNameScalar($value))) {
return $fqnValue;
}
return var_export($value, true);
}
/**
* Process a string configuration key
*
* @param string $key
* @return string
*/
protected function processStringKey($key)
{
if ($this->useClassNameScalars && false !== ($fqnKey = $this->fqnStringToClassNameScalar($key))) {
return $fqnKey;
}
return "'" . addslashes($key) . "'";
}
/**
* Attempts to convert a FQN string to class name scalar.
* Returns false if string is not a valid FQN or can not be resolved to an existing name.
*
* @param string $string
* @return bool|string
*/
protected function fqnStringToClassNameScalar($string)
{
if (strlen($string) < 1) {
return false;
}
if ($string[0] !== '\\') {
$string = '\\' . $string;
}
if ($this->checkStringIsFqn($string)) {
return $string . '::class';
}
return false;
}
/**
* Check whether a string represents a resolvable FQCN
*
* @param string $string
* @return bool
*/
protected function checkStringIsFqn($string)
{
if (!preg_match('/^(?:\x5c[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)+$/', $string)) {
return false;
}
return class_exists($string) || interface_exists($string) || trait_exists($string);
}
}
================================================
FILE: src/Zend/Config/src/Writer/WriterInterface.php
================================================
openMemory();
$writer->setIndent(true);
$writer->setIndentString(str_repeat(' ', 4));
$writer->startDocument('1.0', 'UTF-8');
$writer->startElement('zend-config');
foreach ($config as $sectionName => $data) {
if (!is_array($data)) {
$writer->writeElement($sectionName, (string) $data);
} else {
$this->addBranch($sectionName, $data, $writer);
}
}
$writer->endElement();
$writer->endDocument();
return $writer->outputMemory();
}
/**
* Add a branch to an XML object recursively.
*
* @param string $branchName
* @param array $config
* @param XMLWriter $writer
* @return void
* @throws Exception\RuntimeException
*/
protected function addBranch($branchName, array $config, XMLWriter $writer)
{
$branchType = null;
foreach ($config as $key => $value) {
if ($branchType === null) {
if (is_numeric($key)) {
$branchType = 'numeric';
} else {
$writer->startElement($branchName);
$branchType = 'string';
}
} elseif ($branchType !== (is_numeric($key) ? 'numeric' : 'string')) {
throw new Exception\RuntimeException('Mixing of string and numeric keys is not allowed');
}
if ($branchType === 'numeric') {
if (is_array($value)) {
$this->addBranch($branchName, $value, $writer);
} else {
$writer->writeElement($branchName, (string) $value);
}
} else {
if (is_array($value)) {
$this->addBranch($key, $value, $writer);
} else {
$writer->writeElement($key, (string) $value);
}
}
}
if ($branchType === 'string') {
$writer->endElement();
}
}
}
================================================
FILE: src/Zend/Config/src/Writer/Yaml.php
================================================
setYamlEncoder($yamlEncoder);
} else {
if (function_exists('yaml_emit')) {
$this->setYamlEncoder('yaml_emit');
}
}
}
/**
* Get callback for decoding YAML
*
* @return callable
*/
public function getYamlEncoder()
{
return $this->yamlEncoder;
}
/**
* Set callback for decoding YAML
*
* @param callable $yamlEncoder the decoder to set
* @return Yaml
* @throws Exception\InvalidArgumentException
*/
public function setYamlEncoder($yamlEncoder)
{
if (!is_callable($yamlEncoder)) {
throw new Exception\InvalidArgumentException('Invalid parameter to setYamlEncoder() - must be callable');
}
$this->yamlEncoder = $yamlEncoder;
return $this;
}
/**
* processConfig(): defined by AbstractWriter.
*
* @param array $config
* @return string
* @throws Exception\RuntimeException
*/
public function processConfig(array $config)
{
if (null === $this->getYamlEncoder()) {
throw new Exception\RuntimeException("You didn't specify a Yaml callback encoder");
}
$config = call_user_func($this->getYamlEncoder(), $config);
if (null === $config) {
throw new Exception\RuntimeException("Error generating YAML data");
}
return $config;
}
}
================================================
FILE: src/Zend/Config/src/WriterPluginManager.php
================================================
Writer\Ini::class,
'Ini' => Writer\Ini::class,
'json' => Writer\Json::class,
'Json' => Writer\Json::class,
'php' => Writer\PhpArray::class,
'phparray' => Writer\PhpArray::class,
'phpArray' => Writer\PhpArray::class,
'PhpArray' => Writer\PhpArray::class,
'yaml' => Writer\Yaml::class,
'Yaml' => Writer\Yaml::class,
'xml' => Writer\Xml::class,
'Xml' => Writer\Xml::class,
];
protected $factories = [
Writer\Ini::class => InvokableFactory::class,
Writer\Json::class => InvokableFactory::class,
Writer\PhpArray::class => InvokableFactory::class,
Writer\Yaml::class => InvokableFactory::class,
Writer\Xml::class => InvokableFactory::class,
// Legacy (v2) due to alias resolution; canonical form of resolved
// alias is used to look up the factory, while the non-normalized
// resolved alias is used as the requested name passed to the factory.
'zendconfigwriterini' => InvokableFactory::class,
'zendconfigwriterjson' => InvokableFactory::class,
'zendconfigwriterphparray' => InvokableFactory::class,
'zendconfigwriteryaml' => InvokableFactory::class,
'zendconfigwriterxml' => InvokableFactory::class,
];
/**
* Validate the plugin is of the expected type (v3).
*
* Validates against `$instanceOf`.
*
* @param mixed $instance
* @throws InvalidServiceException
*/
public function validate($instance)
{
if (! $instance instanceof $this->instanceOf) {
throw new InvalidServiceException(sprintf(
'%s can only create instances of %s; %s is invalid',
get_class($this),
$this->instanceOf,
(is_object($instance) ? get_class($instance) : gettype($instance))
));
}
}
/**
* Validate the plugin is of the expected type (v2).
*
* Proxies to `validate()`.
*
* @param mixed $instance
* @throws Exception\InvalidArgumentException
*/
public function validatePlugin($instance)
{
try {
$this->validate($instance);
} catch (InvalidServiceException $e) {
throw new Exception\InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
}
public function __construct(ContainerInterface $container, array $config = [])
{
$config = array_merge_recursive(['aliases' => $this->aliases], $config);
parent::__construct($container, $config);
}
}
================================================
FILE: src/Zend/Crypt/LICENSE.md
================================================
Copyright (c) 2005-2015, Zend Technologies USA, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
- Neither the name of Zend Technologies USA, Inc. nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================
FILE: src/Zend/Crypt/README.md
================================================
# zend-crypt
[](https://secure.travis-ci.org/zendframework/zend-crypt)
[](https://coveralls.io/r/zendframework/zend-crypt?branch=master)
`Zend\Crypt` provides support of some cryptographic tools.
The available features are:
- encrypt-then-authenticate using symmetric ciphers (the authentication step
is provided using HMAC);
- encrypt/decrypt using symmetric and public key algorithm (e.g. RSA algorithm);
- generate digital sign using public key algorithm (e.g. RSA algorithm);
- key exchange using the Diffie-Hellman method;
- key derivation function (e.g. using PBKDF2 algorithm);
- secure password hash (e.g. using Bcrypt algorithm);
- generate Hash values;
- generate HMAC values;
The main scope of this component is to offer an easy and secure way to protect
and authenticate sensitive data in PHP.
- File issues at https://github.com/zendframework/zend-crypt/issues
- Documentation is at http://framework.zend.com/manual/current/en/index.html#zend-crypt
================================================
FILE: src/Zend/Crypt/src/BlockCipher.php
================================================
cipher = $cipher;
}
/**
* Factory
*
* @param string $adapter
* @param array $options
* @return BlockCipher
*/
public static function factory($adapter, $options = [])
{
$plugins = static::getSymmetricPluginManager();
$adapter = $plugins->get($adapter);
$adapter->setOptions($options);
return new static($adapter);
}
/**
* Returns the symmetric cipher plugin manager. If it doesn't exist it's created.
*
* @return ContainerInterface
*/
public static function getSymmetricPluginManager()
{
if (static::$symmetricPlugins === null) {
static::setSymmetricPluginManager(new SymmetricPluginManager());
}
return static::$symmetricPlugins;
}
/**
* Set the symmetric cipher plugin manager
*
* @param string|SymmetricPluginManager $plugins
* @throws Exception\InvalidArgumentException
*/
public static function setSymmetricPluginManager($plugins)
{
if (is_string($plugins)) {
if (!class_exists($plugins) || ! is_subclass_of($plugins, ContainerInterface::class)) {
throw new Exception\InvalidArgumentException(sprintf(
'Unable to locate symmetric cipher plugins using class "%s"; class does not exist or does not implement ContainerInterface',
$plugins
));
}
$plugins = new $plugins();
}
if (!$plugins instanceof ContainerInterface) {
throw new Exception\InvalidArgumentException(sprintf(
'Symmetric plugin must implements Interop\Container\ContainerInterface;; received "%s"',
(is_object($plugins) ? get_class($plugins) : gettype($plugins))
));
}
static::$symmetricPlugins = $plugins;
}
/**
* Set the symmetric cipher
*
* @param SymmetricInterface $cipher
* @return BlockCipher
*/
public function setCipher(SymmetricInterface $cipher)
{
$this->cipher = $cipher;
return $this;
}
/**
* Get symmetric cipher
*
* @return SymmetricInterface
*/
public function getCipher()
{
return $this->cipher;
}
/**
* Set the number of iterations for Pbkdf2
*
* @param int $num
* @return BlockCipher
*/
public function setKeyIteration($num)
{
$this->keyIteration = (int) $num;
return $this;
}
/**
* Get the number of iterations for Pbkdf2
*
* @return int
*/
public function getKeyIteration()
{
return $this->keyIteration;
}
/**
* Set the salt (IV)
*
* @param string $salt
* @return BlockCipher
* @throws Exception\InvalidArgumentException
*/
public function setSalt($salt)
{
try {
$this->cipher->setSalt($salt);
} catch (Symmetric\Exception\InvalidArgumentException $e) {
throw new Exception\InvalidArgumentException("The salt is not valid: " . $e->getMessage());
}
$this->saltSetted = true;
return $this;
}
/**
* Get the salt (IV) according to the size requested by the algorithm
*
* @return string
*/
public function getSalt()
{
return $this->cipher->getSalt();
}
/**
* Get the original salt value
*
* @return string
*/
public function getOriginalSalt()
{
return $this->cipher->getOriginalSalt();
}
/**
* Enable/disable the binary output
*
* @param bool $value
* @return BlockCipher
*/
public function setBinaryOutput($value)
{
$this->binaryOutput = (bool) $value;
return $this;
}
/**
* Get the value of binary output
*
* @return bool
*/
public function getBinaryOutput()
{
return $this->binaryOutput;
}
/**
* Set the encryption/decryption key
*
* @param string $key
* @return BlockCipher
* @throws Exception\InvalidArgumentException
*/
public function setKey($key)
{
if (empty($key)) {
throw new Exception\InvalidArgumentException('The key cannot be empty');
}
$this->key = $key;
return $this;
}
/**
* Get the key
*
* @return string
*/
public function getKey()
{
return $this->key;
}
/**
* Set algorithm of the symmetric cipher
*
* @param string $algo
* @return BlockCipher
* @throws Exception\InvalidArgumentException
*/
public function setCipherAlgorithm($algo)
{
if (empty($this->cipher)) {
throw new Exception\InvalidArgumentException('No symmetric cipher specified');
}
try {
$this->cipher->setAlgorithm($algo);
} catch (Symmetric\Exception\InvalidArgumentException $e) {
throw new Exception\InvalidArgumentException($e->getMessage());
}
return $this;
}
/**
* Get the cipher algorithm
*
* @return string|bool
*/
public function getCipherAlgorithm()
{
if (!empty($this->cipher)) {
return $this->cipher->getAlgorithm();
}
return false;
}
/**
* Get the supported algorithms of the symmetric cipher
*
* @return array
*/
public function getCipherSupportedAlgorithms()
{
if (!empty($this->cipher)) {
return $this->cipher->getSupportedAlgorithms();
}
return [];
}
/**
* Set the hash algorithm for HMAC authentication
*
* @param string $hash
* @return BlockCipher
* @throws Exception\InvalidArgumentException
*/
public function setHashAlgorithm($hash)
{
if (!Hash::isSupported($hash)) {
throw new Exception\InvalidArgumentException(
"The specified hash algorithm '{$hash}' is not supported by Zend\Crypt\Hash"
);
}
$this->hash = $hash;
return $this;
}
/**
* Get the hash algorithm for HMAC authentication
*
* @return string
*/
public function getHashAlgorithm()
{
return $this->hash;
}
/**
* Set the hash algorithm for the Pbkdf2
*
* @param string $hash
* @return BlockCipher
* @throws Exception\InvalidArgumentException
*/
public function setPbkdf2HashAlgorithm($hash)
{
if (!Hash::isSupported($hash)) {
throw new Exception\InvalidArgumentException(
"The specified hash algorithm '{$hash}' is not supported by Zend\Crypt\Hash"
);
}
$this->pbkdf2Hash = $hash;
return $this;
}
/**
* Get the Pbkdf2 hash algorithm
*
* @return string
*/
public function getPbkdf2HashAlgorithm()
{
return $this->pbkdf2Hash;
}
/**
* Encrypt then authenticate using HMAC
*
* @param string $data
* @return string
* @throws Exception\InvalidArgumentException
*/
public function encrypt($data)
{
// 0 (as integer), 0.0 (as float) & '0' (as string) will return false, though these should be allowed
// Must be a string, integer, or float in order to encrypt
if ((is_string($data) && $data === '')
|| is_array($data)
|| is_object($data)
) {
throw new Exception\InvalidArgumentException('The data to encrypt cannot be empty');
}
// Cast to string prior to encrypting
if (!is_string($data)) {
$data = (string) $data;
}
if (empty($this->cipher)) {
throw new Exception\InvalidArgumentException('No symmetric cipher specified');
}
if (empty($this->key)) {
throw new Exception\InvalidArgumentException('No key specified for the encryption');
}
$keySize = $this->cipher->getKeySize();
// generate a random salt (IV) if the salt has not been set
if (!$this->saltSetted) {
$this->cipher->setSalt(Rand::getBytes($this->cipher->getSaltSize(), true));
}
// generate the encryption key and the HMAC key for the authentication
$hash = Pbkdf2::calc(
$this->getPbkdf2HashAlgorithm(),
$this->getKey(),
$this->getSalt(),
$this->keyIteration,
$keySize * 2
);
// set the encryption key
$this->cipher->setKey(substr($hash, 0, $keySize));
// set the key for HMAC
$keyHmac = substr($hash, $keySize);
// encryption
$ciphertext = $this->cipher->encrypt($data);
// HMAC
$hmac = Hmac::compute($keyHmac, $this->hash, $this->cipher->getAlgorithm() . $ciphertext);
if (!$this->binaryOutput) {
$ciphertext = base64_encode($ciphertext);
}
return $hmac . $ciphertext;
}
/**
* Decrypt
*
* @param string $data
* @return string|bool
* @throws Exception\InvalidArgumentException
*/
public function decrypt($data)
{
if (!is_string($data)) {
throw new Exception\InvalidArgumentException('The data to decrypt must be a string');
}
if ('' === $data) {
throw new Exception\InvalidArgumentException('The data to decrypt cannot be empty');
}
if (empty($this->key)) {
throw new Exception\InvalidArgumentException('No key specified for the decryption');
}
if (empty($this->cipher)) {
throw new Exception\InvalidArgumentException('No symmetric cipher specified');
}
$hmacSize = Hmac::getOutputSize($this->hash);
$hmac = substr($data, 0, $hmacSize);
$ciphertext = substr($data, $hmacSize) ?: '';
if (!$this->binaryOutput) {
$ciphertext = base64_decode($ciphertext);
}
$iv = substr($ciphertext, 0, $this->cipher->getSaltSize());
$keySize = $this->cipher->getKeySize();
// generate the encryption key and the HMAC key for the authentication
$hash = Pbkdf2::calc(
$this->getPbkdf2HashAlgorithm(),
$this->getKey(),
$iv,
$this->keyIteration,
$keySize * 2
);
// set the decryption key
$this->cipher->setKey(substr($hash, 0, $keySize));
// set the key for HMAC
$keyHmac = substr($hash, $keySize);
$hmacNew = Hmac::compute($keyHmac, $this->hash, $this->cipher->getAlgorithm() . $ciphertext);
if (!Utils::compareStrings($hmacNew, $hmac)) {
return false;
}
return $this->cipher->decrypt($ciphertext);
}
}
================================================
FILE: src/Zend/Crypt/src/Exception/ExceptionInterface.php
================================================
cipher = new Mcrypt;
}
/**
* Set the cipher object
*
* @param SymmetricInterface $cipher
*/
public function setCipher(SymmetricInterface $cipher)
{
$this->cipher = $cipher;
}
/**
* Get the cipher object
*
* @return SymmetricInterface
*/
public function getCipher()
{
return $this->cipher;
}
/**
* Set the number of iterations for Pbkdf2
*
* @param int $num
*/
public function setKeyIteration($num)
{
$this->keyIteration = (int) $num;
}
/**
* Get the number of iterations for Pbkdf2
*
* @return int
*/
public function getKeyIteration()
{
return $this->keyIteration;
}
/**
* Set the encryption/decryption key
*
* @param string $key
* @throws Exception\InvalidArgumentException
*/
public function setKey($key)
{
if (empty($key)) {
throw new Exception\InvalidArgumentException('The key cannot be empty');
}
$this->key = (string) $key;
}
/**
* Get the key
*
* @return string|null
*/
public function getKey()
{
return $this->key;
}
/**
* Set algorithm of the symmetric cipher
*
* @param string $algo
*/
public function setCipherAlgorithm($algo)
{
$this->cipher->setAlgorithm($algo);
}
/**
* Get the cipher algorithm
*
* @return string|bool
*/
public function getCipherAlgorithm()
{
return $this->cipher->getAlgorithm();
}
/**
* Get the supported algorithms of the symmetric cipher
*
* @return array
*/
public function getCipherSupportedAlgorithms()
{
return $this->cipher->getSupportedAlgorithms();
}
/**
* Set the hash algorithm for HMAC authentication
*
* @param string $hash
* @throws Exception\InvalidArgumentException
*/
public function setHashAlgorithm($hash)
{
if (!Hash::isSupported($hash)) {
throw new Exception\InvalidArgumentException(
"The specified hash algorithm '{$hash}' is not supported by Zend\Crypt\Hash"
);
}
$this->hash = (string) $hash;
}
/**
* Get the hash algorithm for HMAC authentication
*
* @return string
*/
public function getHashAlgorithm()
{
return $this->hash;
}
/**
* Set the hash algorithm for the Pbkdf2
*
* @param string $hash
* @throws Exception\InvalidArgumentException
*/
public function setPbkdf2HashAlgorithm($hash)
{
if (!Hash::isSupported($hash)) {
throw new Exception\InvalidArgumentException(
"The specified hash algorithm '{$hash}' is not supported by Zend\Crypt\Hash"
);
}
$this->pbkdf2Hash = (string) $hash;
}
/**
* Get the Pbkdf2 hash algorithm
*
* @return string
*/
public function getPbkdf2HashAlgorithm()
{
return $this->pbkdf2Hash;
}
/**
* Encrypt then authenticate a file using HMAC
*
* @param string $fileIn
* @param string $fileOut
* @return bool
* @throws Exception\InvalidArgumentException
*/
public function encrypt($fileIn, $fileOut)
{
$this->checkFileInOut($fileIn, $fileOut);
if (empty($this->key)) {
throw new Exception\InvalidArgumentException('No key specified for encryption');
}
$read = fopen($fileIn, "r");
$write = fopen($fileOut, "w");
$iv = Rand::getBytes($this->cipher->getSaltSize(), true);
$keys = Pbkdf2::calc($this->getPbkdf2HashAlgorithm(),
$this->getKey(),
$iv,
$this->getKeyIteration(),
$this->cipher->getKeySize() * 2);
$hmac = '';
$size = 0;
$tot = filesize($fileIn);
$padding = $this->cipher->getPadding();
$this->cipher->setKey(substr($keys, 0, $this->cipher->getKeySize()));
$this->cipher->setPadding(new Symmetric\Padding\NoPadding);
$this->cipher->setSalt($iv);
$this->cipher->setMode('cbc');
$hashAlgo = $this->getHashAlgorithm();
$saltSize = $this->cipher->getSaltSize();
$algorithm = $this->cipher->getAlgorithm();
$keyHmac = substr($keys, $this->cipher->getKeySize());
while ($data = fread($read, self::BUFFER_SIZE)) {
$size += strlen($data);
// Padding if last block
if ($size == $tot) {
$this->cipher->setPadding($padding);
}
$result = $this->cipher->encrypt($data);
if ($size <= self::BUFFER_SIZE) {
// Write a placeholder for the HMAC and write the IV
fwrite($write, str_repeat(0, Hmac::getOutputSize($hashAlgo)));
} else {
$result = substr($result, $saltSize);
}
$hmac = Hmac::compute($keyHmac,
$hashAlgo,
$algorithm . $hmac . $result);
$this->cipher->setSalt(substr($result, -1 * $saltSize));
if (fwrite($write, $result) !== strlen($result)) {
return false;
}
}
$result = true;
// write the HMAC at the beginning of the file
fseek($write, 0);
if (fwrite($write, $hmac) !== strlen($hmac)) {
$result = false;
}
fclose($write);
fclose($read);
return $result;
}
/**
* Decrypt a file
*
* @param string $fileIn
* @param string $fileOut
* @param bool $compress
* @return bool
* @throws Exception\InvalidArgumentException
*/
public function decrypt($fileIn, $fileOut)
{
$this->checkFileInOut($fileIn, $fileOut);
if (empty($this->key)) {
throw new Exception\InvalidArgumentException('No key specified for decryption');
}
$read = fopen($fileIn, "r");
$write = fopen($fileOut, "w");
$hmacRead = fread($read, Hmac::getOutputSize($this->getHashAlgorithm()));
$iv = fread($read, $this->cipher->getSaltSize());
$tot = filesize($fileIn);
$hmac = $iv;
$size = strlen($iv) + strlen($hmacRead);
$keys = Pbkdf2::calc($this->getPbkdf2HashAlgorithm(),
$this->getKey(),
$iv,
$this->getKeyIteration(),
$this->cipher->getKeySize() * 2);
$padding = $this->cipher->getPadding();
$this->cipher->setPadding(new Symmetric\Padding\NoPadding);
$this->cipher->setKey(substr($keys, 0, $this->cipher->getKeySize()));
$this->cipher->setMode('cbc');
$blockSize = $this->cipher->getBlockSize();
$hashAlgo = $this->getHashAlgorithm();
$algorithm = $this->cipher->getAlgorithm();
$saltSize = $this->cipher->getSaltSize();
$keyHmac = substr($keys, $this->cipher->getKeySize());
while ($data = fread($read, self::BUFFER_SIZE)) {
$size += strlen($data);
// Unpadding if last block
if ($size + $blockSize >= $tot) {
$this->cipher->setPadding($padding);
$data .= fread($read, $blockSize);
}
$result = $this->cipher->decrypt($iv . $data);
$hmac = Hmac::compute($keyHmac,
$hashAlgo,
$algorithm . $hmac . $data);
$iv = substr($data, -1 * $saltSize);
if (fwrite($write, $result) !== strlen($result)) {
return false;
}
}
fclose($write);
fclose($read);
// check for data integrity
if (!Utils::compareStrings($hmac, $hmacRead)) {
unlink($fileOut);
return false;
}
return true;
}
/**
* Check that input file exists and output file dont
*
* @param string $fileIn
* @param string $fileOut
* @throws Exception\InvalidArgumentException
*/
protected function checkFileInOut($fileIn, $fileOut)
{
if (!file_exists($fileIn)) {
throw new Exception\InvalidArgumentException(sprintf(
"I cannot open the %s file", $fileIn
));
}
if (file_exists($fileOut)) {
throw new Exception\InvalidArgumentException(sprintf(
"The file %s already exists", $fileOut
));
}
}
}
================================================
FILE: src/Zend/Crypt/src/Hash.php
================================================
MHASH_ADLER32,
'md2' => MHASH_MD2,
'md4' => MHASH_MD4,
'md5' => MHASH_MD5,
'sha1' => MHASH_SHA1,
'sha224' => MHASH_SHA224,
'sha256' => MHASH_SHA256,
'sha384' => MHASH_SHA384,
'sha512' => MHASH_SHA512,
'ripemd128' => MHASH_RIPEMD128,
'ripemd256' => MHASH_RIPEMD256,
'ripemd320' => MHASH_RIPEMD320,
'haval128,3' => MHASH_HAVAL128, // @deprecated use haval128 instead
'haval128' => MHASH_HAVAL128,
'haval160,3' => MHASH_HAVAL160, // @deprecated use haval160 instead
'haval160' => MHASH_HAVAL160,
'haval192,3' => MHASH_HAVAL192, // @deprecated use haval192 instead
'haval192' => MHASH_HAVAL192,
'haval224,3' => MHASH_HAVAL224, // @deprecated use haval224 instead
'haval224' => MHASH_HAVAL224,
'haval256,3' => MHASH_HAVAL256, // @deprecated use haval256 instead
'haval256' => MHASH_HAVAL256,
'tiger' => MHASH_TIGER,
'tiger128,3' => MHASH_TIGER128, // @deprecated use tiger128 instead
'tiger128' => MHASH_TIGER128,
'tiger160,3' => MHASH_TIGER160, // @deprecated use tiger160 instead
'tiger160' => MHASH_TIGER160,
'whirpool' => MHASH_WHIRLPOOL,
'snefru256' => MHASH_SNEFRU256,
'gost' => MHASH_GOST,
'crc32' => MHASH_CRC32,
'crc32b' => MHASH_CRC32B
];
/**
* Generate the new key
*
* @param string $hash The hash algorithm to be used by HMAC
* @param string $password The source password/key
* @param int $bytes The output size in bytes
* @param string $salt The salt of the algorithm
* @throws Exception\InvalidArgumentException
* @return string
*/
public static function calc($hash, $password, $salt, $bytes)
{
if (!in_array($hash, array_keys(static::$supportedMhashAlgos))) {
throw new Exception\InvalidArgumentException("The hash algorithm $hash is not supported by " . __CLASS__);
}
if (strlen($salt)<8) {
throw new Exception\InvalidArgumentException('The salt size must be at least of 8 bytes');
}
return mhash_keygen_s2k(static::$supportedMhashAlgos[$hash], $password, $salt, $bytes);
}
}
================================================
FILE: src/Zend/Crypt/src/Key/Derivation/Scrypt.php
================================================
0 and a power of 2");
}
if ($n > PHP_INT_MAX / 128 / $r) {
throw new Exception\InvalidArgumentException("Parameter n is too large");
}
if ($r > PHP_INT_MAX / 128 / $p) {
throw new Exception\InvalidArgumentException("Parameter r is too large");
}
if (extension_loaded('Scrypt')) {
if ($length < 16) {
throw new Exception\InvalidArgumentException("Key length is too low, must be greater or equal to 16");
}
return hex2bin(scrypt($password, $salt, $n, $r, $p, $length));
}
$b = Pbkdf2::calc('sha256', $password, $salt, 1, $p * 128 * $r);
$s = '';
for ($i = 0; $i < $p; $i++) {
$s .= self::scryptROMix(substr($b, $i * 128 * $r, 128 * $r), $n, $r);
}
return Pbkdf2::calc('sha256', $password, $s, 1, $length);
}
/**
* scryptROMix
*
* @param string $b
* @param int $n
* @param int $r
* @return string
* @see https://tools.ietf.org/html/draft-josefsson-scrypt-kdf-01#section-4
*/
protected static function scryptROMix($b, $n, $r)
{
$x = $b;
$v = [];
for ($i = 0; $i < $n; $i++) {
$v[$i] = $x;
$x = self::scryptBlockMix($x, $r);
}
for ($i = 0; $i < $n; $i++) {
$j = self::integerify($x) % $n;
$t = $x ^ $v[$j];
$x = self::scryptBlockMix($t, $r);
}
return $x;
}
/**
* scryptBlockMix
*
* @param string $b
* @param int $r
* @return string
* @see https://tools.ietf.org/html/draft-josefsson-scrypt-kdf-01#section-3
*/
protected static function scryptBlockMix($b, $r)
{
$x = substr($b, -64);
$even = '';
$odd = '';
$len = 2 * $r;
for ($i = 0; $i < $len; $i++) {
if (PHP_INT_SIZE === 4) {
$x = self::salsa208Core32($x ^ substr($b, 64 * $i, 64));
} else {
$x = self::salsa208Core64($x ^ substr($b, 64 * $i, 64));
}
if ($i % 2 == 0) {
$even .= $x;
} else {
$odd .= $x;
}
}
return $even . $odd;
}
/**
* Salsa 20/8 core (32 bit version)
*
* @param string $b
* @return string
* @see https://tools.ietf.org/html/draft-josefsson-scrypt-kdf-01#section-2
* @see http://cr.yp.to/salsa20.html
*/
protected static function salsa208Core32($b)
{
$b32 = [];
for ($i = 0; $i < 16; $i++) {
list(, $b32[$i]) = unpack("V", substr($b, $i * 4, 4));
}
$x = $b32;
for ($i = 0; $i < 8; $i += 2) {
$a = ($x[ 0] + $x[12]);
$x[ 4] ^= ($a << 7) | ($a >> 25) & 0x7f;
$a = ($x[ 4] + $x[ 0]);
$x[ 8] ^= ($a << 9) | ($a >> 23) & 0x1ff;
$a = ($x[ 8] + $x[ 4]);
$x[12] ^= ($a << 13) | ($a >> 19) & 0x1fff;
$a = ($x[12] + $x[ 8]);
$x[ 0] ^= ($a << 18) | ($a >> 14) & 0x3ffff;
$a = ($x[ 5] + $x[ 1]);
$x[ 9] ^= ($a << 7) | ($a >> 25) & 0x7f;
$a = ($x[ 9] + $x[ 5]);
$x[13] ^= ($a << 9) | ($a >> 23) & 0x1ff;
$a = ($x[13] + $x[ 9]);
$x[ 1] ^= ($a << 13) | ($a >> 19) & 0x1fff;
$a = ($x[ 1] + $x[13]);
$x[ 5] ^= ($a << 18) | ($a >> 14) & 0x3ffff;
$a = ($x[10] + $x[ 6]);
$x[14] ^= ($a << 7) | ($a >> 25) & 0x7f;
$a = ($x[14] + $x[10]);
$x[ 2] ^= ($a << 9) | ($a >> 23) & 0x1ff;
$a = ($x[ 2] + $x[14]);
$x[ 6] ^= ($a << 13) | ($a >> 19) & 0x1fff;
$a = ($x[ 6] + $x[ 2]);
$x[10] ^= ($a << 18) | ($a >> 14) & 0x3ffff;
$a = ($x[15] + $x[11]);
$x[ 3] ^= ($a << 7) | ($a >> 25) & 0x7f;
$a = ($x[ 3] + $x[15]);
$x[ 7] ^= ($a << 9) | ($a >> 23) & 0x1ff;
$a = ($x[ 7] + $x[ 3]);
$x[11] ^= ($a << 13) | ($a >> 19) & 0x1fff;
$a = ($x[11] + $x[ 7]);
$x[15] ^= ($a << 18) | ($a >> 14) & 0x3ffff;
$a = ($x[ 0] + $x[ 3]);
$x[ 1] ^= ($a << 7) | ($a >> 25) & 0x7f;
$a = ($x[ 1] + $x[ 0]);
$x[ 2] ^= ($a << 9) | ($a >> 23) & 0x1ff;
$a = ($x[ 2] + $x[ 1]);
$x[ 3] ^= ($a << 13) | ($a >> 19) & 0x1fff;
$a = ($x[ 3] + $x[ 2]);
$x[ 0] ^= ($a << 18) | ($a >> 14) & 0x3ffff;
$a = ($x[ 5] + $x[ 4]);
$x[ 6] ^= ($a << 7) | ($a >> 25) & 0x7f;
$a = ($x[ 6] + $x[ 5]);
$x[ 7] ^= ($a << 9) | ($a >> 23) & 0x1ff;
$a = ($x[ 7] + $x[ 6]);
$x[ 4] ^= ($a << 13) | ($a >> 19) & 0x1fff;
$a = ($x[ 4] + $x[ 7]);
$x[ 5] ^= ($a << 18) | ($a >> 14) & 0x3ffff;
$a = ($x[10] + $x[ 9]);
$x[11] ^= ($a << 7) | ($a >> 25) & 0x7f;
$a = ($x[11] + $x[10]);
$x[ 8] ^= ($a << 9) | ($a >> 23) & 0x1ff;
$a = ($x[ 8] + $x[11]);
$x[ 9] ^= ($a << 13) | ($a >> 19) & 0x1fff;
$a = ($x[ 9] + $x[ 8]);
$x[10] ^= ($a << 18) | ($a >> 14) & 0x3ffff;
$a = ($x[15] + $x[14]);
$x[12] ^= ($a << 7) | ($a >> 25) & 0x7f;
$a = ($x[12] + $x[15]);
$x[13] ^= ($a << 9) | ($a >> 23) & 0x1ff;
$a = ($x[13] + $x[12]);
$x[14] ^= ($a << 13) | ($a >> 19) & 0x1fff;
$a = ($x[14] + $x[13]);
$x[15] ^= ($a << 18) | ($a >> 14) & 0x3ffff;
}
for ($i = 0; $i < 16; $i++) {
$b32[$i] = $b32[$i] + $x[$i];
}
$result = '';
for ($i = 0; $i < 16; $i++) {
$result .= pack("V", $b32[$i]);
}
return $result;
}
/**
* Salsa 20/8 core (64 bit version)
*
* @param string $b
* @return string
* @see https://tools.ietf.org/html/draft-josefsson-scrypt-kdf-01#section-2
* @see http://cr.yp.to/salsa20.html
*/
protected static function salsa208Core64($b)
{
$b32 = [];
for ($i = 0; $i < 16; $i++) {
list(, $b32[$i]) = unpack("V", substr($b, $i * 4, 4));
}
$x = $b32;
for ($i = 0; $i < 8; $i += 2) {
$a = ($x[ 0] + $x[12]) & 0xffffffff;
$x[ 4] ^= ($a << 7) | ($a >> 25);
$a = ($x[ 4] + $x[ 0]) & 0xffffffff;
$x[ 8] ^= ($a << 9) | ($a >> 23);
$a = ($x[ 8] + $x[ 4]) & 0xffffffff;
$x[12] ^= ($a << 13) | ($a >> 19);
$a = ($x[12] + $x[ 8]) & 0xffffffff;
$x[ 0] ^= ($a << 18) | ($a >> 14);
$a = ($x[ 5] + $x[ 1]) & 0xffffffff;
$x[ 9] ^= ($a << 7) | ($a >> 25);
$a = ($x[ 9] + $x[ 5]) & 0xffffffff;
$x[13] ^= ($a << 9) | ($a >> 23);
$a = ($x[13] + $x[ 9]) & 0xffffffff;
$x[ 1] ^= ($a << 13) | ($a >> 19);
$a = ($x[ 1] + $x[13]) & 0xffffffff;
$x[ 5] ^= ($a << 18) | ($a >> 14);
$a = ($x[10] + $x[ 6]) & 0xffffffff;
$x[14] ^= ($a << 7) | ($a >> 25);
$a = ($x[14] + $x[10]) & 0xffffffff;
$x[ 2] ^= ($a << 9) | ($a >> 23);
$a = ($x[ 2] + $x[14]) & 0xffffffff;
$x[ 6] ^= ($a << 13) | ($a >> 19);
$a = ($x[ 6] + $x[ 2]) & 0xffffffff;
$x[10] ^= ($a << 18) | ($a >> 14);
$a = ($x[15] + $x[11]) & 0xffffffff;
$x[ 3] ^= ($a << 7) | ($a >> 25);
$a = ($x[ 3] + $x[15]) & 0xffffffff;
$x[ 7] ^= ($a << 9) | ($a >> 23);
$a = ($x[ 7] + $x[ 3]) & 0xffffffff;
$x[11] ^= ($a << 13) | ($a >> 19);
$a = ($x[11] + $x[ 7]) & 0xffffffff;
$x[15] ^= ($a << 18) | ($a >> 14);
$a = ($x[ 0] + $x[ 3]) & 0xffffffff;
$x[ 1] ^= ($a << 7) | ($a >> 25);
$a = ($x[ 1] + $x[ 0]) & 0xffffffff;
$x[ 2] ^= ($a << 9) | ($a >> 23);
$a = ($x[ 2] + $x[ 1]) & 0xffffffff;
$x[ 3] ^= ($a << 13) | ($a >> 19);
$a = ($x[ 3] + $x[ 2]) & 0xffffffff;
$x[ 0] ^= ($a << 18) | ($a >> 14);
$a = ($x[ 5] + $x[ 4]) & 0xffffffff;
$x[ 6] ^= ($a << 7) | ($a >> 25);
$a = ($x[ 6] + $x[ 5]) & 0xffffffff;
$x[ 7] ^= ($a << 9) | ($a >> 23);
$a = ($x[ 7] + $x[ 6]) & 0xffffffff;
$x[ 4] ^= ($a << 13) | ($a >> 19);
$a = ($x[ 4] + $x[ 7]) & 0xffffffff;
$x[ 5] ^= ($a << 18) | ($a >> 14);
$a = ($x[10] + $x[ 9]) & 0xffffffff;
$x[11] ^= ($a << 7) | ($a >> 25);
$a = ($x[11] + $x[10]) & 0xffffffff;
$x[ 8] ^= ($a << 9) | ($a >> 23);
$a = ($x[ 8] + $x[11]) & 0xffffffff;
$x[ 9] ^= ($a << 13) | ($a >> 19);
$a = ($x[ 9] + $x[ 8]) & 0xffffffff;
$x[10] ^= ($a << 18) | ($a >> 14);
$a = ($x[15] + $x[14]) & 0xffffffff;
$x[12] ^= ($a << 7) | ($a >> 25);
$a = ($x[12] + $x[15]) & 0xffffffff;
$x[13] ^= ($a << 9) | ($a >> 23);
$a = ($x[13] + $x[12]) & 0xffffffff;
$x[14] ^= ($a << 13) | ($a >> 19);
$a = ($x[14] + $x[13]) & 0xffffffff;
$x[15] ^= ($a << 18) | ($a >> 14);
}
for ($i = 0; $i < 16; $i++) {
$b32[$i] = ($b32[$i] + $x[$i]) & 0xffffffff;
}
$result = '';
for ($i = 0; $i < 16; $i++) {
$result .= pack("V", $b32[$i]);
}
return $result;
}
/**
* Integerify
*
* Integerify (B[0] ... B[2 * r - 1]) is defined as the result
* of interpreting B[2 * r - 1] as a little-endian integer.
* Each block B is a string of 64 bytes.
*
* @param string $b
* @return int
* @see https://tools.ietf.org/html/draft-josefsson-scrypt-kdf-01#section-4
*/
protected static function integerify($b)
{
$v = 'v';
if (PHP_INT_SIZE === 8) {
$v = 'V';
}
list(, $n) = unpack($v, substr($b, -64));
return $n;
}
}
================================================
FILE: src/Zend/Crypt/src/Password/Apache.php
================================================
$value) {
switch (strtolower($key)) {
case 'format':
$this->setFormat($value);
break;
case 'authname':
$this->setAuthName($value);
break;
case 'username':
$this->setUserName($value);
break;
}
}
}
/**
* Generate the hash of a password
*
* @param string $password
* @throws Exception\RuntimeException
* @return string
*/
public function create($password)
{
if (empty($this->format)) {
throw new Exception\RuntimeException(
'You must specify a password format'
);
}
switch ($this->format) {
case 'crypt':
$hash = crypt($password, Rand::getString(2, self::ALPHA64));
break;
case 'sha1':
$hash = '{SHA}' . base64_encode(sha1($password, true));
break;
case 'md5':
$hash = $this->apr1Md5($password);
break;
case 'digest':
if (empty($this->userName) || empty($this->authName)) {
throw new Exception\RuntimeException(
'You must specify UserName and AuthName (realm) to generate the digest'
);
}
$hash = md5($this->userName . ':' . $this->authName . ':' .$password);
break;
}
return $hash;
}
/**
* Verify if a password is correct against a hash value
*
* @param string $password
* @param string $hash
* @return bool
*/
public function verify($password, $hash)
{
if (str_starts_with($hash, '{SHA}')) {
$hash2 = '{SHA}' . base64_encode(sha1($password, true));
return Utils::compareStrings($hash, $hash2);
}
if (str_starts_with($hash, '$apr1$')) {
$token = explode('$', $hash);
if (empty($token[2])) {
throw new Exception\InvalidArgumentException(
'The APR1 password format is not valid'
);
}
$hash2 = $this->apr1Md5($password, $token[2]);
return Utils::compareStrings($hash, $hash2);
}
$bcryptPattern = '/\$2[ay]?\$[0-9]{2}\$[' . addcslashes(static::BASE64, '+/') . '\.]{53}/';
if (strlen($hash) > 13 && ! preg_match($bcryptPattern, $hash)) { // digest
if (empty($this->userName) || empty($this->authName)) {
throw new Exception\RuntimeException(
'You must specify UserName and AuthName (realm) to verify the digest'
);
}
$hash2 = md5($this->userName . ':' . $this->authName . ':' .$password);
return Utils::compareStrings($hash, $hash2);
}
return Utils::compareStrings($hash, crypt($password, $hash));
}
/**
* Set the format of the password
*
* @param string $format
* @throws Exception\InvalidArgumentException
* @return Apache
*/
public function setFormat($format)
{
$format = strtolower($format);
if (!in_array($format, $this->supportedFormat)) {
throw new Exception\InvalidArgumentException(sprintf(
'The format %s specified is not valid. The supported formats are: %s',
$format,
implode(',', $this->supportedFormat)
));
}
$this->format = $format;
return $this;
}
/**
* Get the format of the password
*
* @return string
*/
public function getFormat()
{
return $this->format;
}
/**
* Set the AuthName (for digest authentication)
*
* @param string $name
* @return Apache
*/
public function setAuthName($name)
{
$this->authName = $name;
return $this;
}
/**
* Get the AuthName (for digest authentication)
*
* @return string
*/
public function getAuthName()
{
return $this->authName;
}
/**
* Set the username
*
* @param string $name
* @return Apache
*/
public function setUserName($name)
{
$this->userName = $name;
return $this;
}
/**
* Get the username
*
* @return string
*/
public function getUserName()
{
return $this->userName;
}
/**
* Convert a binary string using the alphabet "./0-9A-Za-z"
*
* @param string $value
* @return string
*/
protected function toAlphabet64($value)
{
return strtr(strrev(substr(base64_encode($value), 2)), self::BASE64, self::ALPHA64);
}
/**
* APR1 MD5 algorithm
*
* @param string $password
* @param null|string $salt
* @return string
*/
protected function apr1Md5($password, $salt = null)
{
if (null === $salt) {
$salt = Rand::getString(8, self::ALPHA64);
} else {
if (strlen($salt) !== 8) {
throw new Exception\InvalidArgumentException(
'The salt value for APR1 algorithm must be 8 characters long'
);
}
for ($i = 0; $i < 8; $i++) {
if (! str_contains(self::ALPHA64, $salt[$i])) {
throw new Exception\InvalidArgumentException(
'The salt value must be a string in the alphabet "./0-9A-Za-z"'
);
}
}
}
$len = strlen($password);
$text = $password . '$apr1$' . $salt;
$bin = pack("H32", md5($password . $salt . $password));
for ($i = $len; $i > 0; $i -= 16) {
$text .= substr($bin, 0, min(16, $i));
}
for ($i = $len; $i > 0; $i >>= 1) {
$text .= ($i & 1) ? chr(0) : $password[0];
}
$bin = pack("H32", md5($text));
for ($i = 0; $i < 1000; $i++) {
$new = ($i & 1) ? $password : $bin;
if ($i % 3) {
$new .= $salt;
}
if ($i % 7) {
$new .= $password;
}
$new .= ($i & 1) ? $bin : $password;
$bin = pack("H32", md5($new));
}
$tmp = '';
for ($i = 0; $i < 5; $i++) {
$k = $i + 6;
$j = $i + 12;
if ($j == 16) {
$j = 5;
}
$tmp = $bin[$i] . $bin[$k] . $bin[$j] . $tmp;
}
$tmp = chr(0) . chr(0) . $bin[11] . $tmp;
return '$apr1$' . $salt . '$' . $this->toAlphabet64($tmp);
}
}
================================================
FILE: src/Zend/Crypt/src/Password/Bcrypt.php
================================================
$value) {
switch (strtolower($key)) {
case 'salt':
$this->setSalt($value);
break;
case 'cost':
$this->setCost($value);
break;
}
}
}
}
/**
* Bcrypt
*
* @param string $password
* @throws Exception\RuntimeException
* @return string
*/
public function create($password)
{
if (empty($this->salt)) {
$salt = Rand::getBytes(self::MIN_SALT_SIZE);
} else {
$salt = $this->salt;
}
$salt64 = substr(str_replace('+', '.', base64_encode($salt)), 0, 22);
/**
* Check for security flaw in the bcrypt implementation used by crypt()
* @see http://php.net/security/crypt_blowfish.php
*/
$prefix = '$2y$';
$hash = crypt($password, $prefix . $this->cost . '$' . $salt64);
if (strlen($hash) < 13) {
throw new Exception\RuntimeException('Error during the bcrypt generation');
}
return $hash;
}
/**
* Verify if a password is correct against a hash value
*
* @param string $password
* @param string $hash
* @throws Exception\RuntimeException when the hash is unable to be processed
* @return bool
*/
public function verify($password, $hash)
{
$result = crypt($password, $hash);
return Utils::compareStrings($hash, $result);
}
/**
* Set the cost parameter
*
* @param int|string $cost
* @throws Exception\InvalidArgumentException
* @return Bcrypt
*/
public function setCost($cost)
{
if (!empty($cost)) {
$cost = (int) $cost;
if ($cost < 4 || $cost > 31) {
throw new Exception\InvalidArgumentException(
'The cost parameter of bcrypt must be in range 04-31'
);
}
$this->cost = sprintf('%1$02d', $cost);
}
return $this;
}
/**
* Get the cost parameter
*
* @return string
*/
public function getCost()
{
return $this->cost;
}
/**
* Set the salt value
*
* @param string $salt
* @throws Exception\InvalidArgumentException
* @return Bcrypt
*/
public function setSalt($salt)
{
if (strlen($salt) < self::MIN_SALT_SIZE) {
throw new Exception\InvalidArgumentException(
'The length of the salt must be at least ' . self::MIN_SALT_SIZE . ' bytes'
);
}
$this->salt = $salt;
return $this;
}
/**
* Get the salt value
*
* @return string
*/
public function getSalt()
{
return $this->salt;
}
/**
* Set the backward compatibility $2a$ instead of $2y$ for PHP 5.3.7+
*
* @return Bcrypt
*@deprecated since zf 2.3 requires PHP >= 5.3.23
*/
public function setBackwardCompatibility()
{
return $this;
}
/**
* Get the backward compatibility
*
* @deprecated since zf 2.3 requires PHP >= 5.3.23
* @return bool
*/
public function getBackwardCompatibility()
{
return false;
}
}
================================================
FILE: src/Zend/Crypt/src/Password/BcryptSha.php
================================================
72 characters.
*/
class BcryptSha extends Bcrypt
{
/**
* BcryptSha
*
* @param string $password
* @throws Exception\RuntimeException
* @return string
*/
public function create($password)
{
return parent::create(Hash::compute('sha256', $password));
}
/**
* Verify if a password is correct against a hash value
*
* @param string $password
* @param string $hash
* @throws Exception\RuntimeException when the hash is unable to be processed
* @return bool
*/
public function verify($password, $hash)
{
return parent::verify(Hash::compute('sha256', $password), $hash);
}
}
================================================
FILE: src/Zend/Crypt/src/Password/Exception/ExceptionInterface.php
================================================
setPrime($prime);
$this->setGenerator($generator);
if ($privateKey !== null) {
$this->setPrivateKey($privateKey, $privateKeyFormat);
}
// set up BigInteger adapter
$this->math = Math\BigInteger\BigInteger::factory();
}
/**
* Set whether to use openssl extension
*
* @static
* @param bool $flag
*/
public static function useOpensslExtension($flag = true)
{
static::$useOpenssl = (bool) $flag;
}
/**
* Generate own public key. If a private number has not already been set,
* one will be generated at this stage.
*
* @return DiffieHellman
* @throws \Zend\Crypt\Exception\RuntimeException
*/
public function generateKeys()
{
if (function_exists('openssl_dh_compute_key') && static::$useOpenssl !== false) {
$details = [
'p' => $this->convert($this->getPrime(), self::FORMAT_NUMBER, self::FORMAT_BINARY),
'g' => $this->convert($this->getGenerator(), self::FORMAT_NUMBER, self::FORMAT_BINARY)
];
if ($this->hasPrivateKey()) {
$details['priv_key'] = $this->convert(
$this->privateKey,
self::FORMAT_NUMBER,
self::FORMAT_BINARY
);
$opensslKeyResource = openssl_pkey_new(['dh' => $details]);
} else {
$opensslKeyResource = openssl_pkey_new([
'dh' => $details,
'private_key_bits' => self::DEFAULT_KEY_SIZE,
'private_key_type' => OPENSSL_KEYTYPE_DH
]);
}
if (false === $opensslKeyResource) {
throw new Exception\RuntimeException(
'Can not generate new key; openssl ' . openssl_error_string()
);
}
$data = openssl_pkey_get_details($opensslKeyResource);
$this->setPrivateKey($data['dh']['priv_key'], self::FORMAT_BINARY);
$this->setPublicKey($data['dh']['pub_key'], self::FORMAT_BINARY);
$this->opensslKeyResource = $opensslKeyResource;
} else {
// Private key is lazy generated in the absence of ext/openssl
$publicKey = $this->math->powmod($this->getGenerator(), $this->getPrivateKey(), $this->getPrime());
$this->setPublicKey($publicKey);
}
return $this;
}
/**
* Setter for the value of the public number
*
* @param string $number
* @param string $format
* @return DiffieHellman
* @throws \Zend\Crypt\Exception\InvalidArgumentException
*/
public function setPublicKey($number, $format = self::FORMAT_NUMBER)
{
$number = $this->convert($number, $format, self::FORMAT_NUMBER);
if (!preg_match('/^\d+$/', $number)) {
throw new Exception\InvalidArgumentException('Invalid parameter; not a positive natural number');
}
$this->publicKey = (string) $number;
return $this;
}
/**
* Returns own public key for communication to the second party to this transaction
*
* @param string $format
* @return string
* @throws \Zend\Crypt\Exception\InvalidArgumentException
*/
public function getPublicKey($format = self::FORMAT_NUMBER)
{
if ($this->publicKey === null) {
throw new Exception\InvalidArgumentException(
'A public key has not yet been generated using a prior call to generateKeys()'
);
}
return $this->convert($this->publicKey, self::FORMAT_NUMBER, $format);
}
/**
* Compute the shared secret key based on the public key received from the
* the second party to this transaction. This should agree to the secret
* key the second party computes on our own public key.
* Once in agreement, the key is known to only to both parties.
* By default, the function expects the public key to be in binary form
* which is the typical format when being transmitted.
*
* If you need the binary form of the shared secret key, call
* getSharedSecretKey() with the optional parameter for Binary output.
*
* @param string $publicKey
* @param string $publicKeyFormat
* @param string $secretKeyFormat
* @return string
* @throws \Zend\Crypt\Exception\InvalidArgumentException
* @throws \Zend\Crypt\Exception\RuntimeException
*/
public function computeSecretKey(
$publicKey,
$publicKeyFormat = self::FORMAT_NUMBER,
$secretKeyFormat = self::FORMAT_NUMBER
) {
if (function_exists('openssl_dh_compute_key') && static::$useOpenssl !== false) {
$publicKey = $this->convert($publicKey, $publicKeyFormat, self::FORMAT_BINARY);
$secretKey = openssl_dh_compute_key($publicKey, $this->opensslKeyResource);
if (false === $secretKey) {
throw new Exception\RuntimeException(
'Can not compute key; openssl ' . openssl_error_string()
);
}
$this->secretKey = $this->convert($secretKey, self::FORMAT_BINARY, self::FORMAT_NUMBER);
} else {
$publicKey = $this->convert($publicKey, $publicKeyFormat, self::FORMAT_NUMBER);
if (!preg_match('/^\d+$/', $publicKey)) {
throw new Exception\InvalidArgumentException(
'Invalid parameter; not a positive natural number'
);
}
$this->secretKey = $this->math->powmod($publicKey, $this->getPrivateKey(), $this->getPrime());
}
return $this->getSharedSecretKey($secretKeyFormat);
}
/**
* Return the computed shared secret key from the DiffieHellman transaction
*
* @param string $format
* @return string
* @throws \Zend\Crypt\Exception\InvalidArgumentException
*/
public function getSharedSecretKey($format = self::FORMAT_NUMBER)
{
if (!isset($this->secretKey)) {
throw new Exception\InvalidArgumentException(
'A secret key has not yet been computed; call computeSecretKey() first'
);
}
return $this->convert($this->secretKey, self::FORMAT_NUMBER, $format);
}
/**
* Setter for the value of the prime number
*
* @param string $number
* @return DiffieHellman
* @throws \Zend\Crypt\Exception\InvalidArgumentException
*/
public function setPrime($number)
{
if (!preg_match('/^\d+$/', $number) || $number < 11) {
throw new Exception\InvalidArgumentException(
'Invalid parameter; not a positive natural number or too small: ' .
'should be a large natural number prime'
);
}
$this->prime = (string) $number;
return $this;
}
/**
* Getter for the value of the prime number
*
* @param string $format
* @return string
* @throws \Zend\Crypt\Exception\InvalidArgumentException
*/
public function getPrime($format = self::FORMAT_NUMBER)
{
if (!isset($this->prime)) {
throw new Exception\InvalidArgumentException('No prime number has been set');
}
return $this->convert($this->prime, self::FORMAT_NUMBER, $format);
}
/**
* Setter for the value of the generator number
*
* @param string $number
* @return DiffieHellman
* @throws \Zend\Crypt\Exception\InvalidArgumentException
*/
public function setGenerator($number)
{
if (!preg_match('/^\d+$/', $number) || $number < 2) {
throw new Exception\InvalidArgumentException(
'Invalid parameter; not a positive natural number greater than 1'
);
}
$this->generator = (string) $number;
return $this;
}
/**
* Getter for the value of the generator number
*
* @param string $format
* @return string
* @throws \Zend\Crypt\Exception\InvalidArgumentException
*/
public function getGenerator($format = self::FORMAT_NUMBER)
{
if (!isset($this->generator)) {
throw new Exception\InvalidArgumentException('No generator number has been set');
}
return $this->convert($this->generator, self::FORMAT_NUMBER, $format);
}
/**
* Setter for the value of the private number
*
* @param string $number
* @param string $format
* @return DiffieHellman
* @throws \Zend\Crypt\Exception\InvalidArgumentException
*/
public function setPrivateKey($number, $format = self::FORMAT_NUMBER)
{
$number = $this->convert($number, $format, self::FORMAT_NUMBER);
if (!preg_match('/^\d+$/', $number)) {
throw new Exception\InvalidArgumentException('Invalid parameter; not a positive natural number');
}
$this->privateKey = (string) $number;
return $this;
}
/**
* Getter for the value of the private number
*
* @param string $format
* @return string
*/
public function getPrivateKey($format = self::FORMAT_NUMBER)
{
if (!$this->hasPrivateKey()) {
$this->setPrivateKey($this->generatePrivateKey(), self::FORMAT_BINARY);
}
return $this->convert($this->privateKey, self::FORMAT_NUMBER, $format);
}
/**
* Check whether a private key currently exists.
*
* @return bool
*/
public function hasPrivateKey()
{
return isset($this->privateKey);
}
/**
* Convert number between formats
*
* @param string $number
* @param string $inputFormat
* @param string $outputFormat
* @return string
*/
protected function convert($number, $inputFormat = self::FORMAT_NUMBER, $outputFormat = self::FORMAT_BINARY)
{
if ($inputFormat == $outputFormat) {
return $number;
}
// convert to number
switch ($inputFormat) {
case self::FORMAT_BINARY:
case self::FORMAT_BTWOC:
$number = $this->math->binToInt($number);
break;
case self::FORMAT_NUMBER:
default:
// do nothing
break;
}
// convert to output format
switch ($outputFormat) {
case self::FORMAT_BINARY:
return $this->math->intToBin($number);
case self::FORMAT_BTWOC:
return $this->math->intToBin($number, true);
case self::FORMAT_NUMBER:
default:
return $number;
}
}
/**
* In the event a private number/key has not been set by the user,
* or generated by ext/openssl, a best attempt will be made to
* generate a random key. Having a random number generator installed
* on linux/bsd is highly recommended! The alternative is not recommended
* for production unless without any other option.
*
* @return string
*/
protected function generatePrivateKey()
{
return Math\Rand::getBytes(strlen($this->getPrime()), true);
}
}
================================================
FILE: src/Zend/Crypt/src/PublicKey/Rsa/AbstractKey.php
================================================
details['bits'];
}
/**
* Retrieve openssl key resource
*
* @return resource
*/
public function getOpensslKeyResource()
{
return $this->opensslKeyResource;
}
/**
* Encrypt using this key
*
* @abstract
* @param string $data
* @return string
*/
abstract public function encrypt($data);
/**
* Decrypt using this key
*
* @abstract
* @param string $data
* @return string
*/
abstract public function decrypt($data);
/**
* Get string representation of this key
*
* @abstract
* @return string
*/
abstract public function toString();
/**
* @return string
*/
public function __toString()
{
return $this->toString();
}
}
================================================
FILE: src/Zend/Crypt/src/PublicKey/Rsa/Exception/ExceptionInterface.php
================================================
pemString = $pemString;
$this->opensslKeyResource = $result;
$this->details = openssl_pkey_get_details($this->opensslKeyResource);
}
/**
* Get the public key
*
* @return PublicKey
*/
public function getPublicKey()
{
if ($this->publicKey === null) {
$this->publicKey = new PublicKey($this->details['key']);
}
return $this->publicKey;
}
/**
* Encrypt using this key
*
* @param string $data
* @param integer $padding
* @return string
* @throws Exception\RuntimeException
* @throws Exception\InvalidArgumentException
*/
public function encrypt($data, $padding = OPENSSL_PKCS1_PADDING)
{
if (empty($data)) {
throw new Exception\InvalidArgumentException('The data to encrypt cannot be empty');
}
$encrypted = '';
$result = openssl_private_encrypt($data, $encrypted, $this->getOpensslKeyResource(), $padding);
if (false === $result) {
throw new Exception\RuntimeException(
'Can not encrypt; openssl ' . openssl_error_string()
);
}
return $encrypted;
}
/**
* Decrypt using this key
*
* Starting in 2.4.9/2.5.2, we changed the default padding to
* OPENSSL_PKCS1_OAEP_PADDING to prevent Bleichenbacher's chosen-ciphertext
* attack.
*
* @see http://archiv.infsec.ethz.ch/education/fs08/secsem/bleichenbacher98.pdf
* @param string $data
* @param integer $padding
* @return string
* @throws Exception\RuntimeException
* @throws Exception\InvalidArgumentException
*/
public function decrypt($data, $padding = OPENSSL_PKCS1_OAEP_PADDING)
{
if (!is_string($data)) {
throw new Exception\InvalidArgumentException('The data to decrypt must be a string');
}
if ('' === $data) {
throw new Exception\InvalidArgumentException('The data to decrypt cannot be empty');
}
$decrypted = '';
$result = openssl_private_decrypt($data, $decrypted, $this->getOpensslKeyResource(), $padding);
if (false === $result) {
throw new Exception\RuntimeException(
'Can not decrypt; openssl ' . openssl_error_string()
);
}
return $decrypted;
}
/**
* @return string
*/
public function toString()
{
return $this->pemString;
}
}
================================================
FILE: src/Zend/Crypt/src/PublicKey/Rsa/PublicKey.php
================================================
certificateString = $pemStringOrCertificate;
} else {
$this->pemString = $pemStringOrCertificate;
}
$this->opensslKeyResource = $result;
$this->details = openssl_pkey_get_details($this->opensslKeyResource);
}
/**
* Encrypt using this key
*
* Starting in 2.4.9/2.5.2, we changed the default padding to
* OPENSSL_PKCS1_OAEP_PADDING to prevent Bleichenbacher's chosen-ciphertext
* attack.
*
* @see http://archiv.infsec.ethz.ch/education/fs08/secsem/bleichenbacher98.pdf
* @param string $data
* @param string $padding
* @throws Exception\InvalidArgumentException
* @throws Exception\RuntimeException
* @return string
*/
public function encrypt($data, $padding = OPENSSL_PKCS1_OAEP_PADDING)
{
if (empty($data)) {
throw new Exception\InvalidArgumentException('The data to encrypt cannot be empty');
}
$encrypted = '';
$result = openssl_public_encrypt($data, $encrypted, $this->getOpensslKeyResource(), $padding);
if (false === $result) {
throw new Exception\RuntimeException(
'Can not encrypt; openssl ' . openssl_error_string()
);
}
return $encrypted;
}
/**
* Decrypt using this key
*
* @param string $data
* @param string $padding
* @throws Exception\InvalidArgumentException
* @throws Exception\RuntimeException
* @return string
*/
public function decrypt($data, $padding = OPENSSL_PKCS1_PADDING)
{
if (!is_string($data)) {
throw new Exception\InvalidArgumentException('The data to decrypt must be a string');
}
if ('' === $data) {
throw new Exception\InvalidArgumentException('The data to decrypt cannot be empty');
}
$decrypted = '';
$result = openssl_public_decrypt($data, $decrypted, $this->getOpensslKeyResource(), $padding);
if (false === $result) {
throw new Exception\RuntimeException(
'Can not decrypt; openssl ' . openssl_error_string()
);
}
return $decrypted;
}
/**
* Get certificate string
*
* @return string
*/
public function getCertificate()
{
return $this->certificateString;
}
/**
* To string
*
* @return string
* @throws Exception\RuntimeException
*/
public function toString()
{
if (!empty($this->certificateString)) {
return $this->certificateString;
} elseif (!empty($this->pemString)) {
return $this->pemString;
}
throw new Exception\RuntimeException('No public key string representation is available');
}
}
================================================
FILE: src/Zend/Crypt/src/PublicKey/Rsa.php
================================================
setPrivateKey($privateKey);
}
if ($publicKey instanceof Rsa\PublicKey) {
$options->setPublicKey($publicKey);
}
return new Rsa($options);
}
/**
* Class constructor
*
* @param RsaOptions|null $options
* @throws Rsa\Exception\RuntimeException
*/
public function __construct(?RsaOptions $options = null)
{
if (!extension_loaded('openssl')) {
throw new Exception\RuntimeException(
'Zend\Crypt\PublicKey\Rsa requires openssl extension to be loaded'
);
}
if ($options === null) {
$this->options = new RsaOptions();
} else {
$this->options = $options;
}
}
/**
* Set options
*
* @param RsaOptions $options
* @return Rsa
*/
public function setOptions(RsaOptions $options)
{
$this->options = $options;
return $this;
}
/**
* Get options
*
* @return RsaOptions
*/
public function getOptions()
{
return $this->options;
}
/**
* Return last openssl error(s)
*
* @return string
*/
public function getOpensslErrorString()
{
$message = '';
while (false !== ($error = openssl_error_string())) {
$message .= $error . "\n";
}
return trim($message);
}
/**
* Sign with private key
*
* @param string $data
* @param Rsa\PrivateKey $privateKey
* @return string
* @throws Rsa\Exception\RuntimeException
*/
public function sign($data, ?Rsa\PrivateKey $privateKey = null)
{
$signature = '';
if (null === $privateKey) {
$privateKey = $this->options->getPrivateKey();
}
$result = openssl_sign(
$data,
$signature,
$privateKey->getOpensslKeyResource(),
$this->options->getOpensslSignatureAlgorithm()
);
if (false === $result) {
throw new Exception\RuntimeException(
'Can not generate signature; openssl ' . $this->getOpensslErrorString()
);
}
if ($this->options->getBinaryOutput()) {
return $signature;
}
return base64_encode($signature);
}
/**
* Verify signature with public key
*
* $signature can be encoded in base64 or not. $mode sets how the input must be processed:
* - MODE_AUTO: Check if the $signature is encoded in base64. Not recommended for performance.
* - MODE_BASE64: Decode $signature using base64 algorithm.
* - MODE_RAW: $signature is not encoded.
*
* @param string $data
* @param string $signature
* @param null|Rsa\PublicKey $publicKey
* @param int $mode Input encoding
* @return bool
* @throws Rsa\Exception\RuntimeException
* @see Rsa::MODE_AUTO
* @see Rsa::MODE_BASE64
* @see Rsa::MODE_RAW
*/
public function verify(
$data,
$signature,
?Rsa\PublicKey $publicKey = null,
$mode = self::MODE_AUTO
) {
if (null === $publicKey) {
$publicKey = $this->options->getPublicKey();
}
switch ($mode) {
case self::MODE_AUTO:
// check if data is encoded in Base64
$output = base64_decode($signature, true);
if ((false !== $output) && ($signature === base64_encode($output))) {
$signature = $output;
}
break;
case self::MODE_BASE64:
$signature = base64_decode($signature);
break;
case self::MODE_RAW:
default:
break;
}
$result = openssl_verify(
$data,
$signature,
$publicKey->getOpensslKeyResource(),
$this->options->getOpensslSignatureAlgorithm()
);
if (-1 === $result) {
throw new Exception\RuntimeException(
'Can not verify signature; openssl ' . $this->getOpensslErrorString()
);
}
return ($result === 1);
}
/**
* Encrypt with private/public key
*
* @param string $data
* @param Rsa\AbstractKey $key
* @return string
* @throws Rsa\Exception\InvalidArgumentException
*/
public function encrypt($data, ?Rsa\AbstractKey $key = null, $padding = null)
{
if (null === $key) {
$key = $this->options->getPublicKey();
}
if (null === $key) {
throw new Exception\InvalidArgumentException('No key specified for the decryption');
}
if (null === $padding) {
$encrypted = $key->encrypt($data);
} else {
$encrypted = $key->encrypt($data, $padding);
}
if ($this->options->getBinaryOutput()) {
return $encrypted;
}
return base64_encode($encrypted);
}
/**
* Decrypt with private/public key
*
* $data can be encoded in base64 or not. $mode sets how the input must be processed:
* - MODE_AUTO: Check if the $signature is encoded in base64. Not recommended for performance.
* - MODE_BASE64: Decode $data using base64 algorithm.
* - MODE_RAW: $data is not encoded.
*
* @param string $data
* @param Rsa\AbstractKey $key
* @param int $mode Input encoding
* @return string
* @throws Rsa\Exception\InvalidArgumentException
* @see Rsa::MODE_AUTO
* @see Rsa::MODE_BASE64
* @see Rsa::MODE_RAW
*/
public function decrypt(
$data,
?Rsa\AbstractKey $key = null,
$mode = self::MODE_AUTO,
$padding = null
) {
if (null === $key) {
$key = $this->options->getPrivateKey();
}
if (null === $key) {
throw new Exception\InvalidArgumentException('No key specified for the decryption');
}
switch ($mode) {
case self::MODE_AUTO:
// check if data is encoded in Base64
$output = base64_decode($data, true);
if ((false !== $output) && ($data === base64_encode($output))) {
$data = $output;
}
break;
case self::MODE_BASE64:
$data = base64_decode($data);
break;
case self::MODE_RAW:
default:
break;
}
if (null === $padding) {
return $key->decrypt($data);
} else {
return $key->decrypt($data, $padding);
}
}
/**
* Generate new private/public key pair
* @see RsaOptions::generateKeys()
*
* @param array $opensslConfig
* @return Rsa
* @throws Rsa\Exception\RuntimeException
*/
public function generateKeys(array $opensslConfig = [])
{
$this->options->generateKeys($opensslConfig);
return $this;
}
}
================================================
FILE: src/Zend/Crypt/src/PublicKey/RsaOptions.php
================================================
privateKey = $key;
$this->publicKey = $this->privateKey->getPublicKey();
return $this;
}
/**
* Get private key
*
* @return null|Rsa\PrivateKey
*/
public function getPrivateKey()
{
return $this->privateKey;
}
/**
* Set public key
*
* @param Rsa\PublicKey $key
* @return RsaOptions
*/
public function setPublicKey(Rsa\PublicKey $key)
{
$this->publicKey = $key;
return $this;
}
/**
* Get public key
*
* @return null|Rsa\PublicKey
*/
public function getPublicKey()
{
return $this->publicKey;
}
/**
* Set pass phrase
*
* @param string $phrase
* @return RsaOptions
*/
public function setPassPhrase($phrase)
{
$this->passPhrase = (string) $phrase;
return $this;
}
/**
* Get pass phrase
*
* @return string
*/
public function getPassPhrase()
{
return $this->passPhrase;
}
/**
* Set hash algorithm
*
* @param string $hash
* @return RsaOptions
* @throws Rsa\Exception\RuntimeException
* @throws Rsa\Exception\InvalidArgumentException
*/
public function setHashAlgorithm($hash)
{
$hashUpper = strtoupper($hash);
if (!defined('OPENSSL_ALGO_' . $hashUpper)) {
throw new Exception\InvalidArgumentException(
"Hash algorithm '{$hash}' is not supported"
);
}
$this->hashAlgorithm = strtolower($hash);
$this->opensslSignatureAlgorithm = constant('OPENSSL_ALGO_' . $hashUpper);
return $this;
}
/**
* Get hash algorithm
*
* @return string
*/
public function getHashAlgorithm()
{
return $this->hashAlgorithm;
}
public function getOpensslSignatureAlgorithm()
{
if (!isset($this->opensslSignatureAlgorithm)) {
$this->opensslSignatureAlgorithm = constant('OPENSSL_ALGO_' . strtoupper($this->hashAlgorithm));
}
return $this->opensslSignatureAlgorithm;
}
/**
* Enable/disable the binary output
*
* @param bool $value
* @return RsaOptions
*/
public function setBinaryOutput($value)
{
$this->binaryOutput = (bool) $value;
return $this;
}
/**
* Get the value of binary output
*
* @return bool
*/
public function getBinaryOutput()
{
return $this->binaryOutput;
}
/**
* Generate new private/public key pair
*
* @param array $opensslConfig
* @return RsaOptions
* @throws Rsa\Exception\RuntimeException
*/
public function generateKeys(array $opensslConfig = [])
{
$opensslConfig = array_replace(
[
'private_key_type' => OPENSSL_KEYTYPE_RSA,
'private_key_bits' => Rsa\AbstractKey::DEFAULT_KEY_SIZE,
'digest_alg' => $this->getHashAlgorithm()
],
$opensslConfig
);
// generate
$resource = openssl_pkey_new($opensslConfig);
if (false === $resource) {
throw new Exception\RuntimeException(
'Can not generate keys; openssl ' . openssl_error_string()
);
}
// export key
$passPhrase = $this->getPassPhrase();
$result = openssl_pkey_export($resource, $private, $passPhrase, $opensslConfig);
if (false === $result) {
throw new Exception\RuntimeException(
'Can not export key; openssl ' . openssl_error_string()
);
}
$details = openssl_pkey_get_details($resource);
$this->privateKey = new Rsa\PrivateKey($private, $passPhrase);
$this->publicKey = new Rsa\PublicKey($details['key']);
return $this;
}
}
================================================
FILE: src/Zend/Crypt/src/Symmetric/Exception/ExceptionInterface.php
================================================
'rijndael-128',
'blowfish' => 'blowfish',
'des' => 'des',
'3des' => 'tripledes',
'tripledes' => 'tripledes',
'cast-128' => 'cast-128',
'cast-256' => 'cast-256',
'rijndael-128' => 'rijndael-128',
'rijndael-192' => 'rijndael-192',
'rijndael-256' => 'rijndael-256',
'saferplus' => 'saferplus',
'serpent' => 'serpent',
'twofish' => 'twofish'
];
/**
* Supported encryption modes
*
* @var array
*/
protected $supportedModes = [
'cbc' => 'cbc',
'cfb' => 'cfb',
'ctr' => 'ctr',
'ofb' => 'ofb',
'nofb' => 'nofb',
'ncfb' => 'ncfb'
];
/**
* Constructor
*
* @param array|Traversable $options
* @throws Exception\RuntimeException
* @throws Exception\InvalidArgumentException
*/
public function __construct($options = [])
{
if (!extension_loaded('mcrypt')) {
throw new Exception\RuntimeException(
'You cannot use ' . __CLASS__ . ' without the Mcrypt extension'
);
}
$this->setOptions($options);
$this->setDefaultOptions($options);
}
/**
* Set default options
*
* @param array $options
* @return void
*/
public function setOptions($options)
{
if (!empty($options)) {
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
} elseif (!is_array($options)) {
throw new Exception\InvalidArgumentException(
'The options parameter must be an array, a Zend\Config\Config object or a Traversable'
);
}
foreach ($options as $key => $value) {
switch (strtolower($key)) {
case 'algo':
case 'algorithm':
$this->setAlgorithm($value);
break;
case 'mode':
$this->setMode($value);
break;
case 'key':
$this->setKey($value);
break;
case 'iv':
case 'salt':
$this->setSalt($value);
break;
case 'padding':
$plugins = static::getPaddingPluginManager();
$padding = $plugins->get($value);
$this->padding = $padding;
break;
}
}
}
}
/**
* Set default options
*
* @param array $options
* @return void
*/
protected function setDefaultOptions($options = [])
{
if (!isset($options['padding'])) {
$plugins = static::getPaddingPluginManager();
$padding = $plugins->get(self::DEFAULT_PADDING);
$this->padding = $padding;
}
}
/**
* Returns the padding plugin manager. If it doesn't exist it's created.
*
* @return Interop\Container\ContainerInterface
*/
public static function getPaddingPluginManager()
{
if (static::$paddingPlugins === null) {
self::setPaddingPluginManager(new PaddingPluginManager());
}
return static::$paddingPlugins;
}
/**
* Set the padding plugin manager
*
* @param string|ContainerInterface $plugins
* @throws Exception\InvalidArgumentException
* @return void
*/
public static function setPaddingPluginManager($plugins)
{
if (is_string($plugins)) {
if (! class_exists($plugins) || ! is_subclass_of($plugins, ContainerInterface::class)) {
throw new Exception\InvalidArgumentException(sprintf(
'Unable to locate padding plugin manager via class "%s"; class does not exist or does not implement ContainerInterface',
$plugins
));
}
$plugins = new $plugins();
}
if (!$plugins instanceof ContainerInterface) {
throw new Exception\InvalidArgumentException(sprintf(
'Padding plugins must implements Interop\Container\ContainerInterface; received "%s"',
(is_object($plugins) ? get_class($plugins) : gettype($plugins))
));
}
static::$paddingPlugins = $plugins;
}
/**
* Get the maximum key size for the selected cipher and mode of operation
*
* @return int
*/
public function getKeySize()
{
return mcrypt_get_key_size($this->supportedAlgos[$this->algo], $this->supportedModes[$this->mode]);
}
/**
* Set the encryption key
* If the key is longer than maximum supported, it will be truncated by getKey().
*
* @param string $key
* @throws Exception\InvalidArgumentException
* @return Mcrypt
*/
public function setKey($key)
{
$keyLen = strlen($key);
if (!$keyLen) {
throw new Exception\InvalidArgumentException('The key cannot be empty');
}
$keySizes = mcrypt_module_get_supported_key_sizes($this->supportedAlgos[$this->algo]);
$maxKey = $this->getKeySize();
/*
* blowfish has $keySizes empty, meaning it can have arbitrary key length.
* the others are more picky.
*/
if (!empty($keySizes) && $keyLen < $maxKey) {
if (!in_array($keyLen, $keySizes)) {
throw new Exception\InvalidArgumentException(
"The size of the key must be one of " . implode(", ", $keySizes) . " bytes or longer"
);
}
}
$this->key = $key;
return $this;
}
/**
* Get the encryption key
*
* @return string
*/
public function getKey()
{
if (empty($this->key)) {
return;
}
return substr($this->key, 0, $this->getKeySize());
}
/**
* Set the encryption algorithm (cipher)
*
* @param string $algo
* @throws Exception\InvalidArgumentException
* @return Mcrypt
*/
public function setAlgorithm($algo)
{
if (!array_key_exists($algo, $this->supportedAlgos)) {
throw new Exception\InvalidArgumentException(
"The algorithm $algo is not supported by " . __CLASS__
);
}
$this->algo = $algo;
return $this;
}
/**
* Get the encryption algorithm
*
* @return string
*/
public function getAlgorithm()
{
return $this->algo;
}
/**
* Set the padding object
*
* @param Padding\PaddingInterface $padding
* @return Mcrypt
*/
public function setPadding(Padding\PaddingInterface $padding)
{
$this->padding = $padding;
return $this;
}
/**
* Get the padding object
*
* @return Padding\PaddingInterface
*/
public function getPadding()
{
return $this->padding;
}
/**
* Encrypt
*
* @param string $data
* @throws Exception\InvalidArgumentException
* @return string
*/
public function encrypt($data)
{
// Cannot encrypt empty string
if (!is_string($data) || $data === '') {
throw new Exception\InvalidArgumentException('The data to encrypt cannot be empty');
}
if (null === $this->getKey()) {
throw new Exception\InvalidArgumentException('No key specified for the encryption');
}
if (null === $this->getSalt()) {
throw new Exception\InvalidArgumentException('The salt (IV) cannot be empty');
}
if (null === $this->getPadding()) {
throw new Exception\InvalidArgumentException('You have to specify a padding method');
}
// padding
$data = $this->padding->pad($data, $this->getBlockSize());
$iv = $this->getSalt();
// encryption
$result = mcrypt_encrypt(
$this->supportedAlgos[$this->algo],
$this->getKey(),
$data,
$this->supportedModes[$this->mode],
$iv
);
return $iv . $result;
}
/**
* Decrypt
*
* @param string $data
* @throws Exception\InvalidArgumentException
* @return string
*/
public function decrypt($data)
{
if (empty($data)) {
throw new Exception\InvalidArgumentException('The data to decrypt cannot be empty');
}
if (null === $this->getKey()) {
throw new Exception\InvalidArgumentException('No key specified for the decryption');
}
if (null === $this->getPadding()) {
throw new Exception\InvalidArgumentException('You have to specify a padding method');
}
$iv = substr($data, 0, $this->getSaltSize());
$ciphertext = substr($data, $this->getSaltSize());
$result = mcrypt_decrypt(
$this->supportedAlgos[$this->algo],
$this->getKey(),
$ciphertext,
$this->supportedModes[$this->mode],
$iv
);
// unpadding
return $this->padding->strip($result);
}
/**
* Get the salt (IV) size
*
* @return int
*/
public function getSaltSize()
{
return mcrypt_get_iv_size($this->supportedAlgos[$this->algo], $this->supportedModes[$this->mode]);
}
/**
* Get the supported algorithms
*
* @return array
*/
public function getSupportedAlgorithms()
{
return array_keys($this->supportedAlgos);
}
/**
* Set the salt (IV)
*
* @param string $salt
* @throws Exception\InvalidArgumentException
* @return Mcrypt
*/
public function setSalt($salt)
{
if (empty($salt)) {
throw new Exception\InvalidArgumentException('The salt (IV) cannot be empty');
}
if (strlen($salt) < $this->getSaltSize()) {
throw new Exception\InvalidArgumentException(
'The size of the salt (IV) must be at least ' . $this->getSaltSize() . ' bytes'
);
}
$this->iv = $salt;
return $this;
}
/**
* Get the salt (IV) according to the size requested by the algorithm
*
* @return string
*/
public function getSalt()
{
if (empty($this->iv)) {
return;
}
if (strlen($this->iv) < $this->getSaltSize()) {
throw new Exception\RuntimeException(
'The size of the salt (IV) must be at least ' . $this->getSaltSize() . ' bytes'
);
}
return substr($this->iv, 0, $this->getSaltSize());
}
/**
* Get the original salt value
*
* @return string
*/
public function getOriginalSalt()
{
return $this->iv;
}
/**
* Set the cipher mode
*
* @param string $mode
* @throws Exception\InvalidArgumentException
* @return Mcrypt
*/
public function setMode($mode)
{
if (!empty($mode)) {
$mode = strtolower($mode);
if (!array_key_exists($mode, $this->supportedModes)) {
throw new Exception\InvalidArgumentException(
"The mode $mode is not supported by " . __CLASS__
);
}
$this->mode = $mode;
}
return $this;
}
/**
* Get the cipher mode
*
* @return string
*/
public function getMode()
{
return $this->mode;
}
/**
* Get all supported encryption modes
*
* @return array
*/
public function getSupportedModes()
{
return array_keys($this->supportedModes);
}
/**
* Get the block size
*
* @return int
*/
public function getBlockSize()
{
return mcrypt_get_block_size($this->supportedAlgos[$this->algo], $this->supportedModes[$this->mode]);
}
}
================================================
FILE: src/Zend/Crypt/src/Symmetric/Padding/NoPadding.php
================================================
Padding\Pkcs7::class,
'nopadding' => Padding\NoPadding::class,
'null' => Padding\NoPadding::class,
];
/**
* Do we have the padding plugin?
*
* @param string $id
* @return bool
*/
public function has($id)
{
return array_key_exists($id, $this->paddings);
}
/**
* Retrieve the padding plugin
*
* @param string $id
* @return Padding\PaddingInterface
*/
public function get($id)
{
$class = $this->paddings[$id];
return new $class();
}
}
================================================
FILE: src/Zend/Crypt/src/Symmetric/SymmetricInterface.php
================================================
Symmetric\Mcrypt::class,
];
/**
* Do we have the symmetric plugin?
*
* @param string $id
* @return bool
*/
public function has($id)
{
return array_key_exists($id, $this->symmetric);
}
/**
* Retrieve the symmetric plugin
*
* @param string $id
* @return Symmetric\SymmetricInterface
*/
public function get($id)
{
$class = $this->symmetric[$id];
return new $class();
}
}
================================================
FILE: src/Zend/Crypt/src/Utils.php
================================================
createProfiler($parameters);
}
$driver = $this->createDriver($parameters);
} elseif (! $driver instanceof Driver\DriverInterface) {
throw new Exception\InvalidArgumentException(
'The supplied or instantiated driver object does not implement Zend\Db\Adapter\Driver\DriverInterface'
);
}
$driver->checkEnvironment();
$this->driver = $driver;
if ($platform === null) {
$platform = $this->createPlatform($parameters);
}
$this->platform = $platform;
$this->queryResultSetPrototype = ($queryResultPrototype) ?: new ResultSet\ResultSet();
if ($profiler) {
$this->setProfiler($profiler);
}
}
/**
* @param Profiler\ProfilerInterface $profiler
* @return self Provides a fluent interface
*/
public function setProfiler(Profiler\ProfilerInterface $profiler)
{
$this->profiler = $profiler;
if ($this->driver instanceof Profiler\ProfilerAwareInterface) {
$this->driver->setProfiler($profiler);
}
return $this;
}
/**
* @return null|Profiler\ProfilerInterface
*/
public function getProfiler()
{
return $this->profiler;
}
/**
* getDriver()
*
* @throws Exception\RuntimeException
* @return Driver\DriverInterface
*/
public function getDriver()
{
if ($this->driver === null) {
throw new Exception\RuntimeException('Driver has not been set or configured for this adapter.');
}
return $this->driver;
}
/**
* @return Platform\PlatformInterface
*/
public function getPlatform()
{
return $this->platform;
}
/**
* @return ResultSet\ResultSetInterface
*/
public function getQueryResultSetPrototype()
{
return $this->queryResultSetPrototype;
}
public function getCurrentSchema()
{
return $this->driver->getConnection()->getCurrentSchema();
}
/**
* query() is a convenience function
*
* @param string $sql
* @param string|array|ParameterContainer $parametersOrQueryMode
* @param \Zend\Db\ResultSet\ResultSetInterface|null $resultPrototype
* @return Driver\StatementInterface|ResultSet\ResultSet
*@throws Exception\InvalidArgumentException
*/
public function query(
$sql,
$parametersOrQueryMode = self::QUERY_MODE_PREPARE,
?ResultSet\ResultSetInterface $resultPrototype = null
) {
if (is_string($parametersOrQueryMode)
&& in_array($parametersOrQueryMode, [self::QUERY_MODE_PREPARE, self::QUERY_MODE_EXECUTE])
) {
$mode = $parametersOrQueryMode;
$parameters = null;
} elseif (is_array($parametersOrQueryMode) || $parametersOrQueryMode instanceof ParameterContainer) {
$mode = self::QUERY_MODE_PREPARE;
$parameters = $parametersOrQueryMode;
} else {
throw new Exception\InvalidArgumentException(
'Parameter 2 to this method must be a flag, an array, or ParameterContainer'
);
}
if ($mode == self::QUERY_MODE_PREPARE) {
$this->lastPreparedStatement = null;
$this->lastPreparedStatement = $this->driver->createStatement($sql);
$this->lastPreparedStatement->prepare();
if (is_array($parameters) || $parameters instanceof ParameterContainer) {
if (is_array($parameters)) {
$this->lastPreparedStatement->setParameterContainer(new ParameterContainer($parameters));
} else {
$this->lastPreparedStatement->setParameterContainer($parameters);
}
$result = $this->lastPreparedStatement->execute();
} else {
return $this->lastPreparedStatement;
}
} else {
$result = $this->driver->getConnection()->execute($sql);
}
if ($result instanceof Driver\ResultInterface && $result->isQueryResult()) {
$resultSet = clone ($resultPrototype ?: $this->queryResultSetPrototype);
$resultSet->initialize($result);
return $resultSet;
}
return $result;
}
/**
* Create statement
*
* @param string $initialSql
* @param ParameterContainer $initialParameters
* @return Driver\StatementInterface
*/
public function createStatement($initialSql = null, $initialParameters = null)
{
$statement = $this->driver->createStatement($initialSql);
if ($initialParameters === null
|| ! $initialParameters instanceof ParameterContainer
&& is_array($initialParameters)
) {
$initialParameters = new ParameterContainer((is_array($initialParameters) ? $initialParameters : []));
}
$statement->setParameterContainer($initialParameters);
return $statement;
}
public function getHelpers()
{
$functions = [];
$platform = $this->platform;
foreach (func_get_args() as $arg) {
switch ($arg) {
case self::FUNCTION_QUOTE_IDENTIFIER:
$functions[] = function ($value) use ($platform) {
return $platform->quoteIdentifier($value);
};
break;
case self::FUNCTION_QUOTE_VALUE:
$functions[] = function ($value) use ($platform) {
return $platform->quoteValue($value);
};
break;
}
}
}
/**
* @param $name
* @throws Exception\InvalidArgumentException
* @return Driver\DriverInterface|Platform\PlatformInterface
*/
public function __get($name)
{
switch (strtolower($name)) {
case 'driver':
return $this->driver;
case 'platform':
return $this->platform;
default:
throw new Exception\InvalidArgumentException('Invalid magic property on adapter');
}
}
/**
* @param array $parameters
* @return Driver\DriverInterface
* @throws \InvalidArgumentException
* @throws Exception\InvalidArgumentException
*/
protected function createDriver($parameters)
{
if (! isset($parameters['driver'])) {
throw new Exception\InvalidArgumentException(
__FUNCTION__ . ' expects a "driver" key to be present inside the parameters'
);
}
if ($parameters['driver'] instanceof Driver\DriverInterface) {
return $parameters['driver'];
}
if (! is_string($parameters['driver'])) {
throw new Exception\InvalidArgumentException(
__FUNCTION__ . ' expects a "driver" to be a string or instance of DriverInterface'
);
}
$options = [];
if (isset($parameters['options'])) {
$options = (array) $parameters['options'];
unset($parameters['options']);
}
$driverName = strtolower($parameters['driver']);
switch ($driverName) {
case 'mysqli':
$driver = new Driver\Mysqli\Mysqli($parameters, null, null, $options);
break;
case 'sqlsrv':
$driver = new Driver\Sqlsrv\Sqlsrv($parameters);
break;
case 'oci8':
$driver = new Driver\Oci8\Oci8($parameters);
break;
case 'pgsql':
$driver = new Driver\Pgsql\Pgsql($parameters);
break;
case 'ibmdb2':
$driver = new Driver\IbmDb2\IbmDb2($parameters);
break;
case 'pdo':
default:
if ($driverName == 'pdo' || str_starts_with($driverName, 'pdo')) {
$driver = new Driver\Pdo\Pdo($parameters);
}
}
if (! isset($driver) || ! $driver instanceof Driver\DriverInterface) {
throw new Exception\InvalidArgumentException('DriverInterface expected', null, null);
}
return $driver;
}
/**
* @param array $parameters
* @return Platform\PlatformInterface
*/
protected function createPlatform(array $parameters)
{
if (isset($parameters['platform'])) {
$platformName = $parameters['platform'];
} elseif ($this->driver instanceof Driver\DriverInterface) {
$platformName = $this->driver->getDatabasePlatformName(Driver\DriverInterface::NAME_FORMAT_CAMELCASE);
} else {
throw new Exception\InvalidArgumentException(
'A platform could not be determined from the provided configuration'
);
}
// currently only supported by the IbmDb2 & Oracle concrete implementations
$options = (isset($parameters['platform_options'])) ? $parameters['platform_options'] : [];
switch ($platformName) {
case 'Mysql':
// mysqli or pdo_mysql driver
if ($this->driver instanceof Driver\Mysqli\Mysqli || $this->driver instanceof Driver\Pdo\Pdo) {
$driver = $this->driver;
} else {
$driver = null;
}
return new Platform\Mysql($driver);
case 'SqlServer':
// PDO is only supported driver for quoting values in this platform
return new Platform\SqlServer(($this->driver instanceof Driver\Pdo\Pdo) ? $this->driver : null);
case 'Oracle':
if ($this->driver instanceof Driver\Oci8\Oci8 || $this->driver instanceof Driver\Pdo\Pdo) {
$driver = $this->driver;
} else {
$driver = null;
}
return new Platform\Oracle($options, $driver);
case 'Sqlite':
// PDO is only supported driver for quoting values in this platform
if ($this->driver instanceof Driver\Pdo\Pdo) {
return new Platform\Sqlite($this->driver);
}
return new Platform\Sqlite(null);
case 'Postgresql':
// pgsql or pdo postgres driver
if ($this->driver instanceof Driver\Pgsql\Pgsql || $this->driver instanceof Driver\Pdo\Pdo) {
$driver = $this->driver;
} else {
$driver = null;
}
return new Platform\Postgresql($driver);
case 'IbmDb2':
// ibm_db2 driver escaping does not need an action connection
return new Platform\IbmDb2($options);
default:
return new Platform\Sql92();
}
}
/**
*
* @param array $parameters
* @return Profiler\ProfilerInterface
* @throws Exception\InvalidArgumentException
*/
protected function createProfiler($parameters)
{
if ($parameters['profiler'] instanceof Profiler\ProfilerInterface) {
$profiler = $parameters['profiler'];
} elseif (is_bool($parameters['profiler'])) {
$profiler = $parameters['profiler'] ? new Profiler\Profiler : null;
} else {
throw new Exception\InvalidArgumentException(
'"profiler" parameter must be an instance of ProfilerInterface or a boolean'
);
}
return $profiler;
}
/**
* @param array $parameters
* @return Driver\DriverInterface
* @throws \InvalidArgumentException
* @throws Exception\InvalidArgumentException
* @deprecated
*/
protected function createDriverFromParameters(array $parameters)
{
return $this->createDriver($parameters);
}
/**
* @param Driver\DriverInterface $driver
* @return Platform\PlatformInterface
* @deprecated
*/
protected function createPlatformFromDriver(Driver\DriverInterface $driver)
{
return $this->createPlatform($driver);
}
}
================================================
FILE: src/Zend/Db/src/Adapter/AdapterAbstractServiceFactory.php
================================================
getConfig($container);
if (empty($config)) {
return false;
}
return (
isset($config[$requestedName])
&& is_array($config[$requestedName])
&& ! empty($config[$requestedName])
);
}
/**
* Determine if we can create a service with name (SM v2 compatibility)
*
* @param ServiceLocatorInterface $serviceLocator
* @param string $name
* @param string $requestedName
* @return bool
*/
public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
{
return $this->canCreate($serviceLocator, $requestedName);
}
/**
* Create a DB adapter
*
* @param ContainerInterface $container
* @param string $requestedName
* @param array|null $options
* @return Adapter
*/
public function __invoke(ContainerInterface $container, $requestedName, ?array $options = null)
{
$config = $this->getConfig($container);
return new Adapter($config[$requestedName]);
}
/**
* Create service with name
*
* @param ServiceLocatorInterface $serviceLocator
* @param string $name
* @param string $requestedName
* @return Adapter
*/
public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
{
return $this($serviceLocator, $requestedName);
}
/**
* Get db configuration, if any
*
* @param ContainerInterface $container
* @return array
*/
protected function getConfig(ContainerInterface $container)
{
if ($this->config !== null) {
return $this->config;
}
if (! $container->has('config')) {
$this->config = [];
return $this->config;
}
$config = $container->get('config');
if (! isset($config['db'])
|| ! is_array($config['db'])
) {
$this->config = [];
return $this->config;
}
$config = $config['db'];
if (! isset($config['adapters'])
|| ! is_array($config['adapters'])
) {
$this->config = [];
return $this->config;
}
$this->config = $config['adapters'];
return $this->config;
}
}
================================================
FILE: src/Zend/Db/src/Adapter/AdapterAwareInterface.php
================================================
adapter = $adapter;
return $this;
}
}
================================================
FILE: src/Zend/Db/src/Adapter/AdapterInterface.php
================================================
get('config');
return new Adapter($config['db']);
}
/**
* Create db adapter service (v2)
*
* @param ServiceLocatorInterface $container
* @return Adapter
*/
public function createService(ServiceLocatorInterface $container)
{
return $this($container, Adapter::class);
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/AbstractConnection.php
================================================
isConnected()) {
$this->resource = null;
}
return $this;
}
/**
* Get connection parameters
*
* @return array
*/
public function getConnectionParameters()
{
return $this->connectionParameters;
}
/**
* Get driver name
*
* @return null|string
*/
public function getDriverName()
{
return $this->driverName;
}
/**
* @return null|ProfilerInterface
*/
public function getProfiler()
{
return $this->profiler;
}
/**
* {@inheritDoc}
*
* @return resource
*/
public function getResource()
{
if (! $this->isConnected()) {
$this->connect();
}
return $this->resource;
}
/**
* Checks whether the connection is in transaction state.
*
* @return boolean
*/
public function inTransaction()
{
return $this->inTransaction;
}
/**
* @param array $connectionParameters
* @return self Provides a fluent interface
*/
public function setConnectionParameters(array $connectionParameters)
{
$this->connectionParameters = $connectionParameters;
return $this;
}
/**
* {@inheritDoc}
*
* @return self Provides a fluent interface
*/
public function setProfiler(ProfilerInterface $profiler)
{
$this->profiler = $profiler;
return $this;
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/ConnectionInterface.php
================================================
driver = $driver;
}
/**
* Get name
*
* @return string
*/
abstract public function getName();
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/Feature/DriverFeatureInterface.php
================================================
setConnectionParameters($connectionParameters);
} elseif (is_resource($connectionParameters)) {
$this->setResource($connectionParameters);
} elseif (null !== $connectionParameters) {
throw new Exception\InvalidArgumentException(
'$connection must be an array of parameters, a db2 connection resource or null'
);
}
}
/**
* Set driver
*
* @param IbmDb2 $driver
* @return self Provides a fluent interface
*/
public function setDriver(IbmDb2 $driver)
{
$this->driver = $driver;
return $this;
}
/**
* @param resource $resource DB2 resource
* @return self Provides a fluent interface
*/
public function setResource($resource)
{
if (! is_resource($resource) || get_resource_type($resource) !== 'DB2 Connection') {
throw new Exception\InvalidArgumentException('The resource provided must be of type "DB2 Connection"');
}
$this->resource = $resource;
return $this;
}
/**
* {@inheritDoc}
*/
public function getCurrentSchema()
{
if (! $this->isConnected()) {
$this->connect();
}
$info = db2_server_info($this->resource);
return ($info->DB_NAME ?? '');
}
/**
* {@inheritDoc}
*/
public function connect()
{
if (is_resource($this->resource)) {
return $this;
}
// localize
$p = $this->connectionParameters;
// given a list of key names, test for existence in $p
$findParameterValue = function (array $names) use ($p) {
foreach ($names as $name) {
if (isset($p[$name])) {
return $p[$name];
}
}
return;
};
$database = $findParameterValue(['database', 'db']);
$username = $findParameterValue(['username', 'uid', 'UID']);
$password = $findParameterValue(['password', 'pwd', 'PWD']);
$isPersistent = $findParameterValue(['persistent', 'PERSISTENT', 'Persistent']);
$options = ($p['driver_options'] ?? []);
$connect = ($isPersistent) ? 'db2_pconnect' : 'db2_connect';
$this->resource = $connect($database, $username, $password, $options);
if ($this->resource === false) {
throw new Exception\RuntimeException(sprintf(
'%s: Unable to connect to database',
__METHOD__
));
}
return $this;
}
/**
* {@inheritDoc}
*/
public function isConnected()
{
return ($this->resource !== null);
}
/**
* {@inheritDoc}
*/
public function disconnect()
{
if ($this->resource) {
db2_close($this->resource);
$this->resource = null;
}
return $this;
}
/**
* {@inheritDoc}
*/
public function beginTransaction()
{
if ($this->isI5() && ! ini_get('ibm_db2.i5_allow_commit')) {
throw new Exception\RuntimeException(
'DB2 transactions are not enabled, you need to set the ibm_db2.i5_allow_commit=1 in your php.ini'
);
}
if (! $this->isConnected()) {
$this->connect();
}
$this->prevAutocommit = db2_autocommit($this->resource);
db2_autocommit($this->resource, DB2_AUTOCOMMIT_OFF);
$this->inTransaction = true;
return $this;
}
/**
* {@inheritDoc}
*/
public function commit()
{
if (! $this->isConnected()) {
$this->connect();
}
if (! db2_commit($this->resource)) {
throw new Exception\RuntimeException("The commit has not been successful");
}
if ($this->prevAutocommit) {
db2_autocommit($this->resource, $this->prevAutocommit);
}
$this->inTransaction = false;
return $this;
}
/**
* Rollback
*
* @return self Provides a fluent interface
* @throws Exception\RuntimeException
*/
public function rollback()
{
if (! $this->isConnected()) {
throw new Exception\RuntimeException('Must be connected before you can rollback.');
}
if (! $this->inTransaction()) {
throw new Exception\RuntimeException('Must call beginTransaction() before you can rollback.');
}
if (! db2_rollback($this->resource)) {
throw new Exception\RuntimeException('The rollback has not been successful');
}
if ($this->prevAutocommit) {
db2_autocommit($this->resource, $this->prevAutocommit);
}
$this->inTransaction = false;
return $this;
}
/**
* {@inheritDoc}
*/
public function execute($sql)
{
if (! $this->isConnected()) {
$this->connect();
}
$this->profiler?->profilerStart($sql);
set_error_handler(function () {
}, E_WARNING); // suppress warnings
$resultResource = db2_exec($this->resource, $sql);
restore_error_handler();
$this->profiler?->profilerFinish($sql);
// if the returnValue is something other than a pg result resource, bypass wrapping it
if ($resultResource === false) {
throw new Exception\InvalidQueryException(db2_stmt_errormsg());
}
return $this->driver->createResult(($resultResource === true) ? $this->resource : $resultResource);
}
/**
* {@inheritDoc}
*/
public function getLastGeneratedValue($name = null)
{
return db2_last_insert_id($this->resource);
}
/**
* Determine if the OS is OS400 (AS400, IBM i)
*
* @return bool
*/
protected function isI5()
{
if (isset($this->i5)) {
return $this->i5;
}
$this->i5 = (php_uname('s') == 'OS400');
return $this->i5;
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/IbmDb2/IbmDb2.php
================================================
registerConnection($connection);
$this->registerStatementPrototype(($statementPrototype) ?: new Statement());
$this->registerResultPrototype(($resultPrototype) ?: new Result());
}
/**
* @param Profiler\ProfilerInterface $profiler
* @return self Provides a fluent interface
*/
public function setProfiler(Profiler\ProfilerInterface $profiler)
{
$this->profiler = $profiler;
if ($this->connection instanceof Profiler\ProfilerAwareInterface) {
$this->connection->setProfiler($profiler);
}
if ($this->statementPrototype instanceof Profiler\ProfilerAwareInterface) {
$this->statementPrototype->setProfiler($profiler);
}
return $this;
}
/**
* @return null|Profiler\ProfilerInterface
*/
public function getProfiler()
{
return $this->profiler;
}
/**
* @param Connection $connection
* @return self Provides a fluent interface
*/
public function registerConnection(Connection $connection)
{
$this->connection = $connection;
$this->connection->setDriver($this);
return $this;
}
/**
* @param Statement $statementPrototype
* @return self Provides a fluent interface
*/
public function registerStatementPrototype(Statement $statementPrototype)
{
$this->statementPrototype = $statementPrototype;
$this->statementPrototype->setDriver($this);
return $this;
}
/**
* @param Result $resultPrototype
* @return self Provides a fluent interface
*/
public function registerResultPrototype(Result $resultPrototype)
{
$this->resultPrototype = $resultPrototype;
return $this;
}
/**
* Get database platform name
*
* @param string $nameFormat
* @return string
*/
public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE)
{
if ($nameFormat == self::NAME_FORMAT_CAMELCASE) {
return 'IbmDb2';
} else {
return 'IBM DB2';
}
}
/**
* Check environment
*
* @return bool
*/
public function checkEnvironment()
{
if (! extension_loaded('ibm_db2')) {
throw new Exception\RuntimeException('The ibm_db2 extension is required by this driver.');
}
}
/**
* Get connection
*
* @return Connection
*/
public function getConnection()
{
return $this->connection;
}
/**
* Create statement
*
* @param string|resource $sqlOrResource
* @return Statement
*/
public function createStatement($sqlOrResource = null)
{
$statement = clone $this->statementPrototype;
if (is_resource($sqlOrResource) && get_resource_type($sqlOrResource) == 'DB2 Statement') {
$statement->setResource($sqlOrResource);
} else {
if (is_string($sqlOrResource)) {
$statement->setSql($sqlOrResource);
} elseif ($sqlOrResource !== null) {
throw new Exception\InvalidArgumentException(
__FUNCTION__ . ' only accepts an SQL string or an ibm_db2 resource'
);
}
if (! $this->connection->isConnected()) {
$this->connection->connect();
}
$statement->initialize($this->connection->getResource());
}
return $statement;
}
/**
* Create result
*
* @param resource $resource
* @return Result
*/
public function createResult($resource)
{
$result = clone $this->resultPrototype;
$result->initialize($resource, $this->connection->getLastGeneratedValue());
return $result;
}
/**
* Get prepare type
*
* @return string
*/
public function getPrepareType()
{
return self::PARAMETERIZATION_POSITIONAL;
}
/**
* Format parameter name
*
* @param string $name
* @param mixed $type
* @return string
*/
public function formatParameterName($name, $type = null)
{
return '?';
}
/**
* Get last generated value
*
* @return mixed
*/
public function getLastGeneratedValue()
{
return $this->connection->getLastGeneratedValue();
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/IbmDb2/Result.php
================================================
resource = $resource;
$this->generatedValue = $generatedValue;
return $this;
}
/**
* (PHP 5 >= 5.0.0)
* Return the current element
* @link http://php.net/manual/en/iterator.current.php
* @return mixed Can return any type.
*/
#[ReturnTypeWillChange] public function current()
{
if ($this->currentComplete) {
return $this->currentData;
}
$this->currentData = db2_fetch_assoc($this->resource);
return $this->currentData;
}
/**
* @return mixed
*/
#[ReturnTypeWillChange] public function next()
{
$this->currentData = db2_fetch_assoc($this->resource);
$this->currentComplete = true;
$this->position++;
return $this->currentData;
}
/**
* @return int|string
*/
#[ReturnTypeWillChange] public function key()
{
return $this->position;
}
/**
* @return bool
*/
#[ReturnTypeWillChange] public function valid()
{
return ($this->currentData !== false);
}
/**
* (PHP 5 >= 5.0.0)
* Rewind the Iterator to the first element
* @link http://php.net/manual/en/iterator.rewind.php
* @return void Any returned value is ignored.
*/
#[ReturnTypeWillChange] public function rewind()
{
if ($this->position > 0) {
throw new Exception\RuntimeException(
'This result is a forward only result set, calling rewind() after moving forward is not supported'
);
}
$this->currentData = db2_fetch_assoc($this->resource);
$this->currentComplete = true;
$this->position = 1;
}
/**
* Force buffering
*
* @return void
*/
public function buffer()
{
return;
}
/**
* Check if is buffered
*
* @return bool|null
*/
public function isBuffered()
{
return false;
}
/**
* Is query result?
*
* @return bool
*/
public function isQueryResult()
{
return (db2_num_fields($this->resource) > 0);
}
/**
* Get affected rows
*
* @return int
*/
public function getAffectedRows()
{
return db2_num_rows($this->resource);
}
/**
* Get generated value
*
* @return mixed|null
*/
public function getGeneratedValue()
{
return $this->generatedValue;
}
/**
* Get the resource
*
* @return mixed
*/
public function getResource()
{
return $this->resource;
}
/**
* Get field count
*
* @return int
*/
public function getFieldCount()
{
return db2_num_fields($this->resource);
}
/**
* @return null|int
*/
#[ReturnTypeWillChange] public function count()
{
return;
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/IbmDb2/Statement.php
================================================
db2 = $resource;
return $this;
}
/**
* @param IbmDb2 $driver
* @return self Provides a fluent interface
*/
public function setDriver(IbmDb2 $driver)
{
$this->driver = $driver;
return $this;
}
/**
* @param Profiler\ProfilerInterface $profiler
* @return self Provides a fluent interface
*/
public function setProfiler(Profiler\ProfilerInterface $profiler)
{
$this->profiler = $profiler;
return $this;
}
/**
* @return null|Profiler\ProfilerInterface
*/
public function getProfiler()
{
return $this->profiler;
}
/**
* Set sql
*
* @param $sql
* @return self Provides a fluent interface
*/
public function setSql($sql)
{
$this->sql = $sql;
return $this;
}
/**
* Get sql
*
* @return mixed
*/
public function getSql()
{
return $this->sql;
}
/**
* Set parameter container
*
* @param ParameterContainer $parameterContainer
* @return self Provides a fluent interface
*/
public function setParameterContainer(ParameterContainer $parameterContainer)
{
$this->parameterContainer = $parameterContainer;
return $this;
}
/**
* Get parameter container
*
* @return mixed
*/
public function getParameterContainer()
{
return $this->parameterContainer;
}
/**
* @param $resource
* @throws \Zend\Db\Adapter\Exception\InvalidArgumentException
*/
public function setResource($resource)
{
if (get_resource_type($resource) !== 'DB2 Statement') {
throw new Exception\InvalidArgumentException('Resource must be of type DB2 Statement');
}
$this->resource = $resource;
}
/**
* Get resource
*
* @return resource
*/
public function getResource()
{
return $this->resource;
}
/**
* Prepare sql
*
* @param string|null $sql
* @return self Provides a fluent interface
* @throws Exception\RuntimeException
*/
public function prepare($sql = null)
{
if ($this->isPrepared) {
throw new Exception\RuntimeException('This statement has been prepared already');
}
if ($sql === null) {
$sql = $this->sql;
}
try {
set_error_handler($this->createErrorHandler());
$this->resource = db2_prepare($this->db2, $sql);
} finally {
restore_error_handler();
}
if ($this->resource === false) {
throw new Exception\RuntimeException(db2_stmt_errormsg(), db2_stmt_error());
}
$this->isPrepared = true;
return $this;
}
/**
* Check if is prepared
*
* @return bool
*/
public function isPrepared()
{
return $this->isPrepared;
}
/**
* Execute
*
* @param null|array|ParameterContainer $parameters
* @return Result
*/
public function execute($parameters = null)
{
if (! $this->isPrepared) {
$this->prepare();
}
/** START Standard ParameterContainer Merging Block */
if (! $this->parameterContainer instanceof ParameterContainer) {
if ($parameters instanceof ParameterContainer) {
$this->parameterContainer = $parameters;
$parameters = null;
} else {
$this->parameterContainer = new ParameterContainer();
}
}
if (is_array($parameters)) {
$this->parameterContainer->setFromArray($parameters);
}
/** END Standard ParameterContainer Merging Block */
$this->profiler?->profilerStart($this);
set_error_handler(function () {
}, E_WARNING); // suppress warnings
$response = db2_execute($this->resource, $this->parameterContainer->getPositionalArray());
restore_error_handler();
$this->profiler?->profilerFinish();
if ($response === false) {
throw new Exception\RuntimeException(db2_stmt_errormsg($this->resource));
}
$result = $this->driver->createResult($this->resource);
return $result;
}
/**
* Creates and returns a callable error handler that raises exceptions.
*
* Only raises exceptions for errors that are within the error_reporting mask.
*
* @return callable
*/
private function createErrorHandler()
{
/**
* @param int $errno
* @param string $errstr
* @param string $errfile
* @param int $errline
* @return void
* @throws ErrorException if error is not within the error_reporting mask.
*/
return function ($errno, $errstr, $errfile, $errline) {
if (! (error_reporting() & $errno)) {
// error_reporting does not include this error
return;
}
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
};
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/Mysqli/Connection.php
================================================
setConnectionParameters($connectionInfo);
} elseif ($connectionInfo instanceof \mysqli) {
$this->setResource($connectionInfo);
} elseif (null !== $connectionInfo) {
throw new Exception\InvalidArgumentException(
'$connection must be an array of parameters, a mysqli object or null'
);
}
}
/**
* @param Mysqli $driver
* @return self Provides a fluent interface
*/
public function setDriver(Mysqli $driver)
{
$this->driver = $driver;
return $this;
}
/**
* {@inheritDoc}
*/
public function getCurrentSchema()
{
if (! $this->isConnected()) {
$this->connect();
}
$result = $this->resource->query('SELECT DATABASE()');
$r = $result->fetch_row();
return $r[0];
}
/**
* Set resource
*
* @param \mysqli $resource
* @return self Provides a fluent interface
*/
public function setResource(\mysqli $resource)
{
$this->resource = $resource;
return $this;
}
/**
* {@inheritDoc}
*/
public function connect()
{
if ($this->resource instanceof \mysqli) {
return $this;
}
// localize
$p = $this->connectionParameters;
// given a list of key names, test for existence in $p
$findParameterValue = function (array $names) use ($p) {
foreach ($names as $name) {
if (isset($p[$name])) {
return $p[$name];
}
}
return;
};
$hostname = $findParameterValue(['hostname', 'host']);
$username = $findParameterValue(['username', 'user']);
$password = $findParameterValue(['password', 'passwd', 'pw']);
$database = $findParameterValue(['database', 'dbname', 'db', 'schema']);
$port = (isset($p['port'])) ? (int) $p['port'] : null;
$socket = (isset($p['socket'])) ? $p['socket'] : null;
$useSSL = (isset($p['use_ssl'])) ? $p['use_ssl'] : 0;
$clientKey = (isset($p['client_key'])) ? $p['client_key'] : null;
$clientCert = (isset($p['client_cert'])) ? $p['client_cert'] : null;
$caCert = (isset($p['ca_cert'])) ? $p['ca_cert'] : null;
$caPath = (isset($p['ca_path'])) ? $p['ca_path'] : null;
$cipher = (isset($p['cipher'])) ? $p['cipher'] : null;
$this->resource = new \mysqli();
$this->resource->init();
if (! empty($p['driver_options'])) {
foreach ($p['driver_options'] as $option => $value) {
if (is_string($option)) {
$option = strtoupper($option);
if (! defined($option)) {
continue;
}
$option = constant($option);
}
$this->resource->options($option, $value);
}
}
$flags = null;
if ($useSSL && ! $socket) {
$this->resource->ssl_set($clientKey, $clientCert, $caCert, $caPath, $cipher);
//MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT is not valid option, needs to be set as flag
if (isset($p['driver_options'][MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT])
) {
$flags = MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT;
}
}
try {
$this->resource->real_connect($hostname, $username, $password, $database, $port, $socket, $flags);
} catch (GenericException) {
throw new Exception\RuntimeException(
'Connection error',
null,
new Exception\ErrorException($this->resource->connect_error, $this->resource->connect_errno)
);
}
if ($this->resource->connect_error) {
throw new Exception\RuntimeException(
'Connection error',
null,
new Exception\ErrorException($this->resource->connect_error, $this->resource->connect_errno)
);
}
if (! empty($p['charset'])) {
$this->resource->set_charset($p['charset']);
}
return $this;
}
/**
* {@inheritDoc}
*/
public function isConnected()
{
return ($this->resource instanceof \mysqli);
}
/**
* {@inheritDoc}
*/
public function disconnect()
{
if ($this->resource instanceof \mysqli) {
$this->resource->close();
}
$this->resource = null;
}
/**
* {@inheritDoc}
*/
public function beginTransaction()
{
if (! $this->isConnected()) {
$this->connect();
}
$this->resource->autocommit(false);
$this->inTransaction = true;
return $this;
}
/**
* {@inheritDoc}
*/
public function commit()
{
if (! $this->isConnected()) {
$this->connect();
}
$this->resource->commit();
$this->inTransaction = false;
$this->resource->autocommit(true);
return $this;
}
/**
* {@inheritDoc}
*/
public function rollback()
{
if (! $this->isConnected()) {
throw new Exception\RuntimeException('Must be connected before you can rollback.');
}
if (! $this->inTransaction) {
throw new Exception\RuntimeException('Must call beginTransaction() before you can rollback.');
}
$this->resource->rollback();
$this->resource->autocommit(true);
$this->inTransaction = false;
return $this;
}
/**
* {@inheritDoc}
*
* @throws Exception\InvalidQueryException
*/
public function execute($sql)
{
if (! $this->isConnected()) {
$this->connect();
}
$this->profiler?->profilerStart($sql);
$resultResource = $this->resource->query($sql);
$this->profiler?->profilerFinish($sql);
// if the returnValue is something other than a mysqli_result, bypass wrapping it
if ($resultResource === false) {
throw new Exception\InvalidQueryException($this->resource->error);
}
$resultPrototype = $this->driver->createResult(($resultResource === true) ? $this->resource : $resultResource);
return $resultPrototype;
}
/**
* {@inheritDoc}
*/
public function getLastGeneratedValue($name = null)
{
return $this->resource->insert_id;
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/Mysqli/Mysqli.php
================================================
false
];
/**
* Constructor
*
* @param array|Connection|\mysqli $connection
* @param Statement|null $statementPrototype
* @param Result|null $resultPrototype
* @param array $options
*/
public function __construct(
$connection,
?Statement $statementPrototype = null,
?Result $resultPrototype = null,
array $options = []
) {
if (! $connection instanceof Connection) {
$connection = new Connection($connection);
}
$options = array_intersect_key(array_merge($this->options, $options), $this->options);
$this->registerConnection($connection);
$this->registerStatementPrototype(($statementPrototype) ?: new Statement($options['buffer_results']));
$this->registerResultPrototype(($resultPrototype) ?: new Result());
}
/**
* @param Profiler\ProfilerInterface $profiler
* @return self Provides a fluent interface
*/
public function setProfiler(Profiler\ProfilerInterface $profiler)
{
$this->profiler = $profiler;
if ($this->connection instanceof Profiler\ProfilerAwareInterface) {
$this->connection->setProfiler($profiler);
}
if ($this->statementPrototype instanceof Profiler\ProfilerAwareInterface) {
$this->statementPrototype->setProfiler($profiler);
}
return $this;
}
/**
* @return null|Profiler\ProfilerInterface
*/
public function getProfiler()
{
return $this->profiler;
}
/**
* Register connection
*
* @param Connection $connection
* @return self Provides a fluent interface
*/
public function registerConnection(Connection $connection)
{
$this->connection = $connection;
$this->connection->setDriver($this); // needs access to driver to createStatement()
return $this;
}
/**
* Register statement prototype
*
* @param Statement $statementPrototype
*/
public function registerStatementPrototype(Statement $statementPrototype)
{
$this->statementPrototype = $statementPrototype;
$this->statementPrototype->setDriver($this); // needs access to driver to createResult()
}
/**
* Get statement prototype
*
* @return null|Statement
*/
public function getStatementPrototype()
{
return $this->statementPrototype;
}
/**
* Register result prototype
*
* @param Result $resultPrototype
*/
public function registerResultPrototype(Result $resultPrototype)
{
$this->resultPrototype = $resultPrototype;
}
/**
* @return null|Result
*/
public function getResultPrototype()
{
return $this->resultPrototype;
}
/**
* Get database platform name
*
* @param string $nameFormat
* @return string
*/
public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE)
{
if ($nameFormat == self::NAME_FORMAT_CAMELCASE) {
return 'Mysql';
}
return 'MySQL';
}
/**
* Check environment
*
* @throws Exception\RuntimeException
* @return void
*/
public function checkEnvironment()
{
if (! extension_loaded('mysqli')) {
throw new Exception\RuntimeException(
'The Mysqli extension is required for this adapter but the extension is not loaded'
);
}
}
/**
* Get connection
*
* @return Connection
*/
public function getConnection()
{
return $this->connection;
}
/**
* Create statement
*
* @param string $sqlOrResource
* @return Statement
*/
public function createStatement($sqlOrResource = null)
{
/**
* @todo Resource tracking
if (is_resource($sqlOrResource) && !in_array($sqlOrResource, $this->resources, true)) {
$this->resources[] = $sqlOrResource;
}
*/
$statement = clone $this->statementPrototype;
if ($sqlOrResource instanceof mysqli_stmt) {
$statement->setResource($sqlOrResource);
} else {
if (is_string($sqlOrResource)) {
$statement->setSql($sqlOrResource);
}
if (! $this->connection->isConnected()) {
$this->connection->connect();
}
$statement->initialize($this->connection->getResource());
}
return $statement;
}
/**
* Create result
*
* @param resource $resource
* @param null|bool $isBuffered
* @return Result
*/
public function createResult($resource, $isBuffered = null)
{
$result = clone $this->resultPrototype;
$result->initialize($resource, $this->connection->getLastGeneratedValue(), $isBuffered);
return $result;
}
/**
* Get prepare type
*
* @return string
*/
public function getPrepareType()
{
return self::PARAMETERIZATION_POSITIONAL;
}
/**
* Format parameter name
*
* @param string $name
* @param mixed $type
* @return string
*/
public function formatParameterName($name, $type = null)
{
return '?';
}
/**
* Get last generated value
*
* @return mixed
*/
public function getLastGeneratedValue()
{
return $this->getConnection()->getLastGeneratedValue();
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/Mysqli/Result.php
================================================
null, 'values' => []];
/**
* @var mixed
*/
protected $generatedValue = null;
/**
* Initialize
*
* @param mixed $resource
* @param mixed $generatedValue
* @param bool|null $isBuffered
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function initialize($resource, $generatedValue, $isBuffered = null)
{
if (! $resource instanceof \mysqli
&& ! $resource instanceof \mysqli_result
&& ! $resource instanceof \mysqli_stmt
) {
throw new Exception\InvalidArgumentException('Invalid resource provided.');
}
if ($isBuffered !== null) {
$this->isBuffered = $isBuffered;
} else {
if ($resource instanceof \mysqli || $resource instanceof \mysqli_result
|| $resource instanceof \mysqli_stmt && $resource->num_rows != 0) {
$this->isBuffered = true;
}
}
$this->resource = $resource;
$this->generatedValue = $generatedValue;
return $this;
}
/**
* Force buffering
*
* @throws Exception\RuntimeException
*/
public function buffer()
{
if ($this->resource instanceof \mysqli_stmt && $this->isBuffered !== true) {
if ($this->position > 0) {
throw new Exception\RuntimeException('Cannot buffer a result set that has started iteration.');
}
$this->resource->store_result();
$this->isBuffered = true;
}
}
/**
* Check if is buffered
*
* @return bool|null
*/
public function isBuffered()
{
return $this->isBuffered;
}
/**
* Return the resource
*
* @return mixed
*/
public function getResource()
{
return $this->resource;
}
/**
* Is query result?
*
* @return bool
*/
public function isQueryResult()
{
return ($this->resource->field_count > 0);
}
/**
* Get affected rows
*
* @return int
*/
public function getAffectedRows()
{
if ($this->resource instanceof \mysqli || $this->resource instanceof \mysqli_stmt) {
return $this->resource->affected_rows;
}
return $this->resource->num_rows;
}
/**
* Current
*
* @return mixed
*/
#[ReturnTypeWillChange] public function current()
{
if ($this->currentComplete) {
return $this->currentData;
}
if ($this->resource instanceof \mysqli_stmt) {
$this->loadDataFromMysqliStatement();
return $this->currentData;
} else {
$this->loadFromMysqliResult();
return $this->currentData;
}
}
/**
* Mysqli's binding and returning of statement values
*
* Mysqli requires you to bind variables to the extension in order to
* get data out. These values have to be references:
* @see http://php.net/manual/en/mysqli-stmt.bind-result.php
*
* @throws Exception\RuntimeException
* @return bool
*/
protected function loadDataFromMysqliStatement()
{
// build the default reference based bind structure, if it does not already exist
if ($this->statementBindValues['keys'] === null) {
$this->statementBindValues['keys'] = [];
$resultResource = $this->resource->result_metadata();
foreach ($resultResource->fetch_fields() as $col) {
$this->statementBindValues['keys'][] = $col->name;
}
$this->statementBindValues['values'] = array_fill(0, count($this->statementBindValues['keys']), null);
$refs = [];
foreach ($this->statementBindValues['values'] as $i => &$f) {
$refs[$i] = &$f;
}
call_user_func_array([$this->resource, 'bind_result'], $this->statementBindValues['values']);
}
if (($r = $this->resource->fetch()) === null) {
if (! $this->isBuffered) {
$this->resource->close();
}
return false;
} elseif ($r === false) {
throw new Exception\RuntimeException($this->resource->error);
}
// dereference
for ($i = 0, $count = count($this->statementBindValues['keys']); $i < $count; $i++) {
$this->currentData[$this->statementBindValues['keys'][$i]] = $this->statementBindValues['values'][$i];
}
$this->currentComplete = true;
$this->nextComplete = true;
$this->position++;
return true;
}
/**
* Load from mysqli result
*
* @return bool
*/
protected function loadFromMysqliResult()
{
$this->currentData = null;
if (($data = $this->resource->fetch_assoc()) === null) {
return false;
}
$this->position++;
$this->currentData = $data;
$this->currentComplete = true;
$this->nextComplete = true;
$this->position++;
return true;
}
/**
* Next
*
* @return void
*/
#[ReturnTypeWillChange] public function next()
{
$this->currentComplete = false;
if (! $this->nextComplete) {
$this->position++;
}
$this->nextComplete = false;
}
/**
* Key
*
* @return mixed
*/
#[ReturnTypeWillChange] public function key()
{
return $this->position;
}
/**
* Rewind
*
* @throws Exception\RuntimeException
* @return void
*/
#[ReturnTypeWillChange] public function rewind()
{
if (0 !== $this->position && false === $this->isBuffered) {
throw new Exception\RuntimeException('Unbuffered results cannot be rewound for multiple iterations');
}
$this->resource->data_seek(0); // works for both mysqli_result & mysqli_stmt
$this->currentComplete = false;
$this->position = 0;
}
/**
* Valid
*
* @return bool
*/
#[ReturnTypeWillChange] public function valid()
{
if ($this->currentComplete) {
return true;
}
if ($this->resource instanceof \mysqli_stmt) {
return $this->loadDataFromMysqliStatement();
}
return $this->loadFromMysqliResult();
}
/**
* Count
*
* @throws Exception\RuntimeException
* @return int
*/
#[ReturnTypeWillChange] public function count()
{
if ($this->isBuffered === false) {
throw new Exception\RuntimeException('Row count is not available in unbuffered result sets.');
}
return $this->resource->num_rows;
}
/**
* Get field count
*
* @return int
*/
public function getFieldCount()
{
return $this->resource->field_count;
}
/**
* Get generated value
*
* @return mixed|null
*/
public function getGeneratedValue()
{
return $this->generatedValue;
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/Mysqli/Statement.php
================================================
bufferResults = (bool) $bufferResults;
}
/**
* Set driver
*
* @param Mysqli $driver
* @return self Provides a fluent interface
*/
public function setDriver(Mysqli $driver)
{
$this->driver = $driver;
return $this;
}
/**
* @param Profiler\ProfilerInterface $profiler
* @return self Provides a fluent interface
*/
public function setProfiler(Profiler\ProfilerInterface $profiler)
{
$this->profiler = $profiler;
return $this;
}
/**
* @return null|Profiler\ProfilerInterface
*/
public function getProfiler()
{
return $this->profiler;
}
/**
* Initialize
*
* @param \mysqli $mysqli
* @return self Provides a fluent interface
*/
public function initialize(\mysqli $mysqli)
{
$this->mysqli = $mysqli;
return $this;
}
/**
* Set sql
*
* @param string $sql
* @return self Provides a fluent interface
*/
public function setSql($sql)
{
$this->sql = $sql;
return $this;
}
/**
* Set Parameter container
*
* @param ParameterContainer $parameterContainer
* @return self Provides a fluent interface
*/
public function setParameterContainer(ParameterContainer $parameterContainer)
{
$this->parameterContainer = $parameterContainer;
return $this;
}
/**
* Get resource
*
* @return mixed
*/
public function getResource()
{
return $this->resource;
}
/**
* Set resource
*
* @param \mysqli_stmt $mysqliStatement
* @return self Provides a fluent interface
*/
public function setResource(\mysqli_stmt $mysqliStatement)
{
$this->resource = $mysqliStatement;
$this->isPrepared = true;
return $this;
}
/**
* Get sql
*
* @return string
*/
public function getSql()
{
return $this->sql;
}
/**
* Get parameter count
*
* @return ParameterContainer
*/
public function getParameterContainer()
{
return $this->parameterContainer;
}
/**
* Is prepared
*
* @return bool
*/
public function isPrepared()
{
return $this->isPrepared;
}
/**
* Prepare
*
* @param string $sql
* @return self Provides a fluent interface
* @throws Exception\InvalidQueryException
* @throws Exception\RuntimeException
*/
public function prepare($sql = null)
{
if ($this->isPrepared) {
throw new Exception\RuntimeException('This statement has already been prepared');
}
$sql = ($sql) ?: $this->sql;
$this->resource = $this->mysqli->prepare($sql);
if (! $this->resource instanceof \mysqli_stmt) {
throw new Exception\InvalidQueryException(
'Statement couldn\'t be produced with sql: ' . $sql,
null,
new Exception\ErrorException($this->mysqli->error, $this->mysqli->errno)
);
}
$this->isPrepared = true;
return $this;
}
/**
* Execute
*
* @param null|array|ParameterContainer $parameters
* @throws Exception\RuntimeException
* @return mixed
*/
public function execute($parameters = null)
{
if (! $this->isPrepared) {
$this->prepare();
}
/** START Standard ParameterContainer Merging Block */
if (! $this->parameterContainer instanceof ParameterContainer) {
if ($parameters instanceof ParameterContainer) {
$this->parameterContainer = $parameters;
$parameters = null;
} else {
$this->parameterContainer = new ParameterContainer();
}
}
if (is_array($parameters)) {
$this->parameterContainer->setFromArray($parameters);
}
if ($this->parameterContainer->count() > 0) {
$this->bindParametersFromContainer();
}
/** END Standard ParameterContainer Merging Block */
$this->profiler?->profilerStart($this);
$return = $this->resource->execute();
$this->profiler?->profilerFinish();
if ($return === false) {
throw new Exception\RuntimeException($this->resource->error);
}
if ($this->bufferResults === true) {
$this->resource->store_result();
$this->isPrepared = false;
$buffered = true;
} else {
$buffered = false;
}
$result = $this->driver->createResult($this->resource, $buffered);
return $result;
}
/**
* Bind parameters from container
*
* @return void
*/
protected function bindParametersFromContainer()
{
$parameters = $this->parameterContainer->getNamedArray();
$type = '';
$args = [];
foreach ($parameters as $name => &$value) {
if ($this->parameterContainer->offsetHasErrata($name)) {
switch ($this->parameterContainer->offsetGetErrata($name)) {
case ParameterContainer::TYPE_DOUBLE:
$type .= 'd';
break;
case ParameterContainer::TYPE_NULL:
$value = null;
break; // as per @see http://www.php.net/manual/en/mysqli-stmt.bind-param.php#96148
case ParameterContainer::TYPE_INTEGER:
$type .= 'i';
break;
case ParameterContainer::TYPE_STRING:
default:
$type .= 's';
break;
}
} else {
$type .= 's';
}
$args[] = &$value;
}
if ($args) {
array_unshift($args, $type);
call_user_func_array([$this->resource, 'bind_param'], $args);
}
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/Oci8/Connection.php
================================================
setConnectionParameters($connectionInfo);
} elseif ($connectionInfo instanceof \oci8) {
$this->setResource($connectionInfo);
} elseif (null !== $connectionInfo) {
throw new Exception\InvalidArgumentException(
'$connection must be an array of parameters, an oci8 resource or null'
);
}
}
/**
* @param Oci8 $driver
* @return self Provides a fluent interface
*/
public function setDriver(Oci8 $driver)
{
$this->driver = $driver;
return $this;
}
/**
* {@inheritDoc}
*/
public function getCurrentSchema()
{
if (! $this->isConnected()) {
$this->connect();
}
$query = "SELECT sys_context('USERENV', 'CURRENT_SCHEMA') as \"current_schema\" FROM DUAL";
$stmt = oci_parse($this->resource, $query);
oci_execute($stmt);
$dbNameArray = oci_fetch_array($stmt, OCI_ASSOC);
return $dbNameArray['current_schema'];
}
/**
* Set resource
*
* @param resource $resource
* @return self Provides a fluent interface
*/
public function setResource($resource)
{
if (! is_resource($resource) || get_resource_type($resource) !== 'oci8 connection') {
throw new Exception\InvalidArgumentException('A resource of type "oci8 connection" was expected');
}
$this->resource = $resource;
return $this;
}
/**
* {@inheritDoc}
*/
public function connect()
{
if (is_resource($this->resource)) {
return $this;
}
// localize
$p = $this->connectionParameters;
// given a list of key names, test for existence in $p
$findParameterValue = function (array $names) use ($p) {
foreach ($names as $name) {
if (isset($p[$name])) {
return $p[$name];
}
}
return;
};
// http://www.php.net/manual/en/function.oci-connect.php
$username = $findParameterValue(['username']);
$password = $findParameterValue(['password']);
$connectionString = $findParameterValue([
'connection_string',
'connectionstring',
'connection',
'hostname',
'instance'
]);
$characterSet = $findParameterValue(['character_set', 'charset', 'encoding']);
$sessionMode = $findParameterValue(['session_mode']);
// connection modifiers
$isUnique = $findParameterValue(['unique']);
$isPersistent = $findParameterValue(['persistent']);
if ($isUnique) {
$this->resource = oci_new_connect($username, $password, $connectionString, $characterSet, $sessionMode);
} elseif ($isPersistent) {
$this->resource = oci_pconnect($username, $password, $connectionString, $characterSet, $sessionMode);
} else {
$this->resource = oci_connect($username, $password, $connectionString, $characterSet, $sessionMode);
}
if (! $this->resource) {
$e = oci_error();
throw new Exception\RuntimeException(
'Connection error',
null,
new Exception\ErrorException($e['message'], $e['code'])
);
}
return $this;
}
/**
* {@inheritDoc}
*/
public function isConnected()
{
return (is_resource($this->resource));
}
/**
* {@inheritDoc}
*/
public function disconnect()
{
if (is_resource($this->resource)) {
oci_close($this->resource);
}
}
/**
* {@inheritDoc}
*/
public function beginTransaction()
{
if (! $this->isConnected()) {
$this->connect();
}
// A transaction begins when the first SQL statement that changes data is executed with oci_execute() using
// the OCI_NO_AUTO_COMMIT flag.
$this->inTransaction = true;
return $this;
}
/**
* {@inheritDoc}
*/
public function commit()
{
if (! $this->isConnected()) {
$this->connect();
}
if ($this->inTransaction()) {
$valid = oci_commit($this->resource);
if ($valid === false) {
$e = oci_error($this->resource);
throw new Exception\InvalidQueryException($e['message'], $e['code']);
}
$this->inTransaction = false;
}
return $this;
}
/**
* {@inheritDoc}
*/
public function rollback()
{
if (! $this->isConnected()) {
throw new Exception\RuntimeException('Must be connected before you can rollback.');
}
if (! $this->inTransaction()) {
throw new Exception\RuntimeException('Must call commit() before you can rollback.');
}
$valid = oci_rollback($this->resource);
if ($valid === false) {
$e = oci_error($this->resource);
throw new Exception\InvalidQueryException($e['message'], $e['code']);
}
$this->inTransaction = false;
return $this;
}
/**
* {@inheritDoc}
*/
public function execute($sql)
{
if (! $this->isConnected()) {
$this->connect();
}
$this->profiler?->profilerStart($sql);
$ociStmt = oci_parse($this->resource, $sql);
if ($this->inTransaction) {
$valid = @oci_execute($ociStmt, OCI_NO_AUTO_COMMIT);
} else {
$valid = @oci_execute($ociStmt, OCI_COMMIT_ON_SUCCESS);
}
$this->profiler?->profilerFinish($sql);
if ($valid === false) {
$e = oci_error($ociStmt);
throw new Exception\InvalidQueryException($e['message'], $e['code']);
}
$resultPrototype = $this->driver->createResult($ociStmt);
return $resultPrototype;
}
/**
* {@inheritDoc}
*/
public function getLastGeneratedValue($name = null)
{
// @todo Get Last Generated Value in Connection (this might not apply)
return;
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/Oci8/Feature/RowCounter.php
================================================
getSql();
if ($sql == '' || stripos(strtolower($sql), 'select') === false) {
return;
}
$countSql = 'SELECT COUNT(*) as "count" FROM (' . $sql . ')';
$countStmt->prepare($countSql);
$result = $countStmt->execute();
$countRow = $result->current();
return $countRow['count'];
}
/**
* @param string $sql
* @return null|int
*/
public function getCountForSql($sql)
{
if (stripos(strtolower($sql), 'select') === false) {
return;
}
$countSql = 'SELECT COUNT(*) as "count" FROM (' . $sql . ')';
$result = $this->driver->getConnection()->execute($countSql);
$countRow = $result->current();
return $countRow['count'];
}
/**
* @param \Zend\Db\Adapter\Driver\Oci8\Statement|string $context
* @return callable
*/
public function getRowCountClosure($context)
{
$rowCounter = $this;
return function () use ($rowCounter, $context) {
/** @var $rowCounter RowCounter */
return ($context instanceof Statement)
? $rowCounter->getCountForStatement($context)
: $rowCounter->getCountForSql($context);
};
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/Oci8/Oci8.php
================================================
registerConnection($connection);
$this->registerStatementPrototype(($statementPrototype) ?: new Statement());
$this->registerResultPrototype(($resultPrototype) ?: new Result());
if (is_array($features)) {
foreach ($features as $name => $feature) {
$this->addFeature($name, $feature);
}
} elseif ($features instanceof AbstractFeature) {
$this->addFeature($features->getName(), $features);
} elseif ($features === self::FEATURES_DEFAULT) {
$this->setupDefaultFeatures();
}
}
/**
* @param Profiler\ProfilerInterface $profiler
* @return self Provides a fluent interface
*/
public function setProfiler(Profiler\ProfilerInterface $profiler)
{
$this->profiler = $profiler;
if ($this->connection instanceof Profiler\ProfilerAwareInterface) {
$this->connection->setProfiler($profiler);
}
if ($this->statementPrototype instanceof Profiler\ProfilerAwareInterface) {
$this->statementPrototype->setProfiler($profiler);
}
return $this;
}
/**
* @return null|Profiler\ProfilerInterface
*/
public function getProfiler()
{
return $this->profiler;
}
/**
* Register connection
*
* @param Connection $connection
* @return self Provides a fluent interface
*/
public function registerConnection(Connection $connection)
{
$this->connection = $connection;
$this->connection->setDriver($this); // needs access to driver to createStatement()
return $this;
}
/**
* Register statement prototype
*
* @param Statement $statementPrototype
* @return self Provides a fluent interface
*/
public function registerStatementPrototype(Statement $statementPrototype)
{
$this->statementPrototype = $statementPrototype;
$this->statementPrototype->setDriver($this); // needs access to driver to createResult()
return $this;
}
/**
* @return null|Statement
*/
public function getStatementPrototype()
{
return $this->statementPrototype;
}
/**
* Register result prototype
*
* @param Result $resultPrototype
* @return self Provides a fluent interface
*/
public function registerResultPrototype(Result $resultPrototype)
{
$this->resultPrototype = $resultPrototype;
return $this;
}
/**
* @return null|Result
*/
public function getResultPrototype()
{
return $this->resultPrototype;
}
/**
* Add feature
*
* @param string $name
* @param AbstractFeature $feature
* @return self Provides a fluent interface
*/
public function addFeature($name, $feature)
{
if ($feature instanceof AbstractFeature) {
$name = $feature->getName(); // overwrite the name, just in case
$feature->setDriver($this);
}
$this->features[$name] = $feature;
return $this;
}
/**
* Setup the default features for Pdo
*
* @return self Provides a fluent interface
*/
public function setupDefaultFeatures()
{
$this->addFeature(null, new Feature\RowCounter());
return $this;
}
/**
* Get feature
*
* @param string $name
* @return AbstractFeature|false
*/
public function getFeature($name)
{
if (isset($this->features[$name])) {
return $this->features[$name];
}
return false;
}
/**
* Get database platform name
*
* @param string $nameFormat
* @return string
*/
public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE)
{
return 'Oracle';
}
/**
* Check environment
*/
public function checkEnvironment()
{
if (! extension_loaded('oci8')) {
throw new Exception\RuntimeException(
'The Oci8 extension is required for this adapter but the extension is not loaded'
);
}
}
/**
* @return Connection
*/
public function getConnection()
{
return $this->connection;
}
/**
* @param string $sqlOrResource
* @return Statement
*/
public function createStatement($sqlOrResource = null)
{
$statement = clone $this->statementPrototype;
if (is_resource($sqlOrResource) && get_resource_type($sqlOrResource) == 'oci8 statement') {
$statement->setResource($sqlOrResource);
} else {
if (is_string($sqlOrResource)) {
$statement->setSql($sqlOrResource);
} elseif ($sqlOrResource !== null) {
throw new Exception\InvalidArgumentException(
'Oci8 only accepts an SQL string or an oci8 resource in ' . __FUNCTION__
);
}
if (! $this->connection->isConnected()) {
$this->connection->connect();
}
$statement->initialize($this->connection->getResource());
}
return $statement;
}
/**
* @param resource $resource
* @param null $context
* @return Result
*/
public function createResult($resource, $context = null)
{
$result = clone $this->resultPrototype;
$rowCount = null;
// special feature, oracle Oci counter
if ($context && ($rowCounter = $this->getFeature('RowCounter')) && oci_num_fields($resource) > 0) {
$rowCount = $rowCounter->getRowCountClosure($context);
}
$result->initialize($resource, null, $rowCount);
return $result;
}
/**
* @return string
*/
public function getPrepareType()
{
return self::PARAMETERIZATION_NAMED;
}
/**
* @param string $name
* @param mixed $type
* @return string
*/
public function formatParameterName($name, $type = null)
{
return ':' . $name;
}
/**
* @return mixed
*/
public function getLastGeneratedValue()
{
return $this->getConnection()->getLastGeneratedValue();
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/Oci8/Result.php
================================================
null, 'values' => []];
/**
* @var mixed
*/
protected $generatedValue = null;
/**
* Initialize
* @param resource $resource
* @param null|int $generatedValue
* @param null|int $rowCount
* @return self Provides a fluent interface
*/
public function initialize($resource, $generatedValue = null, $rowCount = null)
{
if (! is_resource($resource) && get_resource_type($resource) !== 'oci8 statement') {
throw new Exception\InvalidArgumentException('Invalid resource provided.');
}
$this->resource = $resource;
$this->generatedValue = $generatedValue;
$this->rowCount = $rowCount;
return $this;
}
/**
* Force buffering at driver level
*
* Oracle does not support this, to my knowledge (@ralphschindler)
*
* @throws Exception\RuntimeException
*/
public function buffer()
{
return;
}
/**
* Is the result buffered?
*
* @return bool
*/
public function isBuffered()
{
return false;
}
/**
* Return the resource
* @return mixed
*/
public function getResource()
{
return $this->resource;
}
/**
* Is query result?
*
* @return bool
*/
public function isQueryResult()
{
return (oci_num_fields($this->resource) > 0);
}
/**
* Get affected rows
* @return int
*/
public function getAffectedRows()
{
return oci_num_rows($this->resource);
}
/**
* Current
* @return mixed
*/
#[ReturnTypeWillChange] public function current()
{
if (! $this->currentComplete) {
if ($this->loadData() === false) {
return false;
}
}
return $this->currentData;
}
/**
* Load from oci8 result
*
* @return bool
*/
protected function loadData()
{
$this->currentComplete = true;
$this->currentData = oci_fetch_assoc($this->resource);
if ($this->currentData !== false) {
$this->position++;
return true;
}
return false;
}
/**
* Next
*/
#[ReturnTypeWillChange] public function next()
{
return $this->loadData();
}
/**
* Key
* @return mixed
*/
#[ReturnTypeWillChange] public function key()
{
return $this->position;
}
/**
* Rewind
*/
#[ReturnTypeWillChange] public function rewind()
{
if ($this->position > 0) {
throw new Exception\RuntimeException('Oci8 results cannot be rewound for multiple iterations');
}
}
/**
* Valid
* @return bool
*/
#[ReturnTypeWillChange] public function valid()
{
if ($this->currentComplete) {
return ($this->currentData !== false);
}
return $this->loadData();
}
/**
* Count
* @return null|int
*/
#[ReturnTypeWillChange] public function count()
{
if (is_int($this->rowCount)) {
return $this->rowCount;
}
if (is_callable($this->rowCount)) {
$this->rowCount = (int) call_user_func($this->rowCount);
return $this->rowCount;
}
return;
}
/**
* @return int
*/
public function getFieldCount()
{
return oci_num_fields($this->resource);
}
/**
* @return null
*/
public function getGeneratedValue()
{
// @todo OCI8 generated value in Driver Result
return;
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/Oci8/Statement.php
================================================
driver = $driver;
return $this;
}
/**
* @param Profiler\ProfilerInterface $profiler
* @return self Provides a fluent interface
*/
public function setProfiler(Profiler\ProfilerInterface $profiler)
{
$this->profiler = $profiler;
return $this;
}
/**
* @return null|Profiler\ProfilerInterface
*/
public function getProfiler()
{
return $this->profiler;
}
/**
* Initialize
*
* @param resource $oci8
* @return self Provides a fluent interface
*/
public function initialize($oci8)
{
$this->oci8 = $oci8;
return $this;
}
/**
* Set sql
*
* @param string $sql
* @return self Provides a fluent interface
*/
public function setSql($sql)
{
$this->sql = $sql;
return $this;
}
/**
* Set Parameter container
*
* @param ParameterContainer $parameterContainer
* @return self Provides a fluent interface
*/
public function setParameterContainer(ParameterContainer $parameterContainer)
{
$this->parameterContainer = $parameterContainer;
return $this;
}
/**
* Get resource
*
* @return mixed
*/
public function getResource()
{
return $this->resource;
}
/**
* Set resource
*
* @param resource $oci8Statement
* @return self Provides a fluent interface
*/
public function setResource($oci8Statement)
{
$type = oci_statement_type($oci8Statement);
if (false === $type || 'UNKNOWN' == $type) {
throw new Exception\InvalidArgumentException(sprintf(
'Invalid statement provided to %s',
__METHOD__
));
}
$this->resource = $oci8Statement;
$this->isPrepared = true;
return $this;
}
/**
* Get sql
*
* @return string
*/
public function getSql()
{
return $this->sql;
}
/**
* @return ParameterContainer
*/
public function getParameterContainer()
{
return $this->parameterContainer;
}
/**
* @return bool
*/
public function isPrepared()
{
return $this->isPrepared;
}
/**
* @param string $sql
* @return self Provides a fluent interface
*/
public function prepare($sql = null)
{
if ($this->isPrepared) {
throw new Exception\RuntimeException('This statement has already been prepared');
}
$sql = ($sql) ?: $this->sql;
// get oci8 statement resource
$this->resource = oci_parse($this->oci8, $sql);
if (! $this->resource) {
$e = oci_error($this->oci8);
throw new Exception\InvalidQueryException(
'Statement couldn\'t be produced with sql: ' . $sql,
null,
new Exception\ErrorException($e['message'], $e['code'])
);
}
$this->isPrepared = true;
return $this;
}
/**
* Execute
*
* @param null|array|ParameterContainer $parameters
* @return mixed
*/
public function execute($parameters = null)
{
if (! $this->isPrepared) {
$this->prepare();
}
/** START Standard ParameterContainer Merging Block */
if (! $this->parameterContainer instanceof ParameterContainer) {
if ($parameters instanceof ParameterContainer) {
$this->parameterContainer = $parameters;
$parameters = null;
} else {
$this->parameterContainer = new ParameterContainer();
}
}
if (is_array($parameters)) {
$this->parameterContainer->setFromArray($parameters);
}
if ($this->parameterContainer->count() > 0) {
$this->bindParametersFromContainer();
}
/** END Standard ParameterContainer Merging Block */
$this->profiler?->profilerStart($this);
if ($this->driver->getConnection()->inTransaction()) {
$ret = @oci_execute($this->resource, OCI_NO_AUTO_COMMIT);
} else {
$ret = @oci_execute($this->resource, OCI_COMMIT_ON_SUCCESS);
}
$this->profiler?->profilerFinish();
if ($ret === false) {
$e = oci_error($this->resource);
throw new Exception\RuntimeException($e['message'], $e['code']);
}
$result = $this->driver->createResult($this->resource, $this);
return $result;
}
/**
* Bind parameters from container
*/
protected function bindParametersFromContainer()
{
$parameters = $this->parameterContainer->getNamedArray();
foreach ($parameters as $name => &$value) {
if ($this->parameterContainer->offsetHasErrata($name)) {
switch ($this->parameterContainer->offsetGetErrata($name)) {
case ParameterContainer::TYPE_NULL:
$type = null;
$value = null;
break;
case ParameterContainer::TYPE_DOUBLE:
case ParameterContainer::TYPE_INTEGER:
$type = SQLT_INT;
if (is_string($value)) {
$value = (int) $value;
}
break;
case ParameterContainer::TYPE_BINARY:
$type = SQLT_BIN;
break;
case ParameterContainer::TYPE_LOB:
$type = OCI_B_CLOB;
$clob = oci_new_descriptor($this->driver->getConnection()->getResource(), OCI_DTYPE_LOB);
$clob->writetemporary($value, OCI_TEMP_CLOB);
$value = $clob;
break;
case ParameterContainer::TYPE_STRING:
default:
$type = SQLT_CHR;
break;
}
} else {
$type = SQLT_CHR;
}
$maxLength = -1;
if ($this->parameterContainer->offsetHasMaxLength($name)) {
$maxLength = $this->parameterContainer->offsetGetMaxLength($name);
}
oci_bind_by_name($this->resource, $name, $value, $maxLength, $type);
}
}
/**
* Perform a deep clone
*/
public function __clone()
{
$this->isPrepared = false;
$this->parametersBound = false;
$this->resource = null;
if ($this->parameterContainer) {
$this->parameterContainer = clone $this->parameterContainer;
}
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/Pdo/Connection.php
================================================
setConnectionParameters($connectionParameters);
} elseif ($connectionParameters instanceof \PDO) {
$this->setResource($connectionParameters);
} elseif (null !== $connectionParameters) {
throw new Exception\InvalidArgumentException(
'$connection must be an array of parameters, a PDO object or null'
);
}
}
/**
* Set driver
*
* @param Pdo $driver
* @return self Provides a fluent interface
*/
public function setDriver(Pdo $driver)
{
$this->driver = $driver;
return $this;
}
/**
* {@inheritDoc}
*/
public function setConnectionParameters(array $connectionParameters)
{
$this->connectionParameters = $connectionParameters;
if (isset($connectionParameters['dsn'])) {
$this->driverName = substr(
$connectionParameters['dsn'],
0,
strpos($connectionParameters['dsn'], ':')
);
} elseif (isset($connectionParameters['pdodriver'])) {
$this->driverName = strtolower($connectionParameters['pdodriver']);
} elseif (isset($connectionParameters['driver'])) {
$this->driverName = strtolower(substr(
str_replace(['-', '_', ' '], '', $connectionParameters['driver']),
3
));
}
}
/**
* Get the dsn string for this connection
* @throws \Zend\Db\Adapter\Exception\RunTimeException
* @return string
*/
public function getDsn()
{
if (! $this->dsn) {
throw new Exception\RuntimeException(
'The DSN has not been set or constructed from parameters in connect() for this Connection'
);
}
return $this->dsn;
}
/**
* {@inheritDoc}
*/
public function getCurrentSchema()
{
if (! $this->isConnected()) {
$this->connect();
}
switch ($this->driverName) {
case 'mysql':
$sql = 'SELECT DATABASE()';
break;
case 'sqlite':
return 'main';
case 'sqlsrv':
case 'dblib':
$sql = 'SELECT SCHEMA_NAME()';
break;
case 'pgsql':
default:
$sql = 'SELECT CURRENT_SCHEMA';
break;
}
/** @var $result \PDOStatement */
$result = $this->resource->query($sql);
if ($result instanceof \PDOStatement) {
return $result->fetchColumn();
}
return false;
}
/**
* Set resource
*
* @param \PDO $resource
* @return self Provides a fluent interface
*/
public function setResource(\PDO $resource)
{
$this->resource = $resource;
$this->driverName = strtolower($this->resource->getAttribute(\PDO::ATTR_DRIVER_NAME));
return $this;
}
/**
* {@inheritDoc}
*
* @throws Exception\InvalidConnectionParametersException
* @throws Exception\RuntimeException
*/
public function connect()
{
if ($this->resource) {
return $this;
}
$dsn = $username = $password = $hostname = $database = null;
$options = [];
foreach ($this->connectionParameters as $key => $value) {
switch (strtolower($key)) {
case 'dsn':
$dsn = $value;
break;
case 'driver':
$value = strtolower((string) $value);
if (str_starts_with($value, 'pdo')) {
$pdoDriver = str_replace(['-', '_', ' '], '', $value);
$pdoDriver = substr($pdoDriver, 3) ?: '';
}
break;
case 'pdodriver':
$pdoDriver = (string) $value;
break;
case 'user':
case 'username':
$username = (string) $value;
break;
case 'pass':
case 'password':
$password = (string) $value;
break;
case 'host':
case 'hostname':
$hostname = (string) $value;
break;
case 'port':
$port = (int) $value;
break;
case 'database':
case 'dbname':
$database = (string) $value;
break;
case 'charset':
$charset = (string) $value;
break;
case 'unix_socket':
$unix_socket = (string) $value;
break;
case 'version':
$version = (string) $value;
break;
case 'driver_options':
case 'options':
$value = (array) $value;
$options = array_diff_key($options, $value) + $value;
break;
default:
$options[$key] = $value;
break;
}
}
if (isset($hostname) && isset($unix_socket)) {
throw new Exception\InvalidConnectionParametersException(
'Ambiguous connection parameters, both hostname and unix_socket parameters were set',
$this->connectionParameters
);
}
if (! isset($dsn) && isset($pdoDriver)) {
$dsn = [];
switch ($pdoDriver) {
case 'sqlite':
$dsn[] = $database;
break;
case 'sqlsrv':
if (isset($database)) {
$dsn[] = "database={$database}";
}
if (isset($hostname)) {
$dsn[] = "server={$hostname}";
}
break;
default:
if (isset($database)) {
$dsn[] = "dbname={$database}";
}
if (isset($hostname)) {
$dsn[] = "host={$hostname}";
}
if (isset($port)) {
$dsn[] = "port={$port}";
}
if (isset($charset) && $pdoDriver != 'pgsql') {
$dsn[] = "charset={$charset}";
}
if (isset($unix_socket)) {
$dsn[] = "unix_socket={$unix_socket}";
}
if (isset($version)) {
$dsn[] = "version={$version}";
}
break;
}
$dsn = $pdoDriver . ':' . implode(';', $dsn);
} elseif (! isset($dsn)) {
throw new Exception\InvalidConnectionParametersException(
'A dsn was not provided or could not be constructed from your parameters',
$this->connectionParameters
);
}
$this->dsn = $dsn;
try {
$this->resource = new \PDO($dsn, $username, $password, $options);
$this->resource->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
if (isset($charset) && $pdoDriver == 'pgsql') {
$this->resource->exec('SET NAMES ' . $this->resource->quote($charset));
}
$this->driverName = strtolower($this->resource->getAttribute(\PDO::ATTR_DRIVER_NAME));
} catch (\PDOException $e) {
$code = $e->getCode();
if (! is_long($code)) {
$code = null;
}
throw new Exception\RuntimeException('Connect Error: ' . $e->getMessage(), $code, $e);
}
return $this;
}
/**
* {@inheritDoc}
*/
public function isConnected()
{
return ($this->resource instanceof \PDO);
}
/**
* {@inheritDoc}
*/
public function beginTransaction()
{
if (! $this->isConnected()) {
$this->connect();
}
if (0 === $this->nestedTransactionsCount) {
$this->resource->beginTransaction();
$this->inTransaction = true;
}
$this->nestedTransactionsCount ++;
return $this;
}
/**
* {@inheritDoc}
*/
public function commit()
{
if (! $this->isConnected()) {
$this->connect();
}
if ($this->inTransaction) {
$this->nestedTransactionsCount -= 1;
}
/*
* This shouldn't check for being in a transaction since
* after issuing a SET autocommit=0; we have to commit too.
*/
if (0 === $this->nestedTransactionsCount) {
$this->resource->commit();
$this->inTransaction = false;
}
return $this;
}
/**
* {@inheritDoc}
*
* @throws Exception\RuntimeException
*/
public function rollback()
{
if (! $this->isConnected()) {
throw new Exception\RuntimeException('Must be connected before you can rollback');
}
if (! $this->inTransaction()) {
throw new Exception\RuntimeException('Must call beginTransaction() before you can rollback');
}
$this->resource->rollBack();
$this->inTransaction = false;
$this->nestedTransactionsCount = 0;
return $this;
}
/**
* {@inheritDoc}
*
* @throws Exception\InvalidQueryException
*/
public function execute($sql)
{
if (! $this->isConnected()) {
$this->connect();
}
$this->profiler?->profilerStart($sql);
$resultResource = $this->resource->query($sql);
$this->profiler?->profilerFinish($sql);
if ($resultResource === false) {
$errorInfo = $this->resource->errorInfo();
throw new Exception\InvalidQueryException($errorInfo[2]);
}
$result = $this->driver->createResult($resultResource, $sql);
return $result;
}
/**
* Prepare
*
* @param string $sql
* @return Statement
*/
public function prepare($sql)
{
if (! $this->isConnected()) {
$this->connect();
}
$statement = $this->driver->createStatement($sql);
return $statement;
}
/**
* {@inheritDoc}
*
* @param string $name
* @return string|null|false
*/
public function getLastGeneratedValue($name = null)
{
if ($name === null
&& ($this->driverName == 'pgsql' || $this->driverName == 'firebird')) {
return;
}
try {
return $this->resource->lastInsertId($name);
} catch (\Exception) {
// do nothing
}
return false;
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/Pdo/Feature/OracleRowCounter.php
================================================
getSql();
if ($sql == '' || stripos($sql, 'select') === false) {
return;
}
$countSql = 'SELECT COUNT(*) as "count" FROM (' . $sql . ')';
$countStmt->prepare($countSql);
$result = $countStmt->execute();
$countRow = $result->getResource()->fetch(\PDO::FETCH_ASSOC);
unset($statement, $result);
return $countRow['count'];
}
/**
* @param $sql
* @return null|int
*/
public function getCountForSql($sql)
{
if (stripos($sql, 'select') === false) {
return;
}
$countSql = 'SELECT COUNT(*) as count FROM (' . $sql . ')';
/** @var $pdo \PDO */
$pdo = $this->driver->getConnection()->getResource();
$result = $pdo->query($countSql);
$countRow = $result->fetch(\PDO::FETCH_ASSOC);
return $countRow['count'];
}
/**
* @param $context
* @return \Closure
*/
public function getRowCountClosure($context)
{
return function () use ($context) {
return ($context instanceof Pdo\Statement)
? $this->getCountForStatement($context)
: $this->getCountForSql($context);
};
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/Pdo/Feature/SqliteRowCounter.php
================================================
getSql();
if ($sql == '' || stripos($sql, 'select') === false) {
return;
}
$countSql = 'SELECT COUNT(*) as "count" FROM (' . $sql . ')';
$countStmt->prepare($countSql);
$result = $countStmt->execute();
$countRow = $result->getResource()->fetch(\PDO::FETCH_ASSOC);
unset($statement, $result);
return $countRow['count'];
}
/**
* @param $sql
* @return null|int
*/
public function getCountForSql($sql)
{
if (stripos($sql, 'select') === false) {
return;
}
$countSql = 'SELECT COUNT(*) as count FROM (' . $sql . ')';
/** @var $pdo \PDO */
$pdo = $this->driver->getConnection()->getResource();
$result = $pdo->query($countSql);
$countRow = $result->fetch(\PDO::FETCH_ASSOC);
return $countRow['count'];
}
/**
* @param $context
* @return \Closure
*/
public function getRowCountClosure($context)
{
return function () use ($context) {
return ($context instanceof Pdo\Statement)
? $this->getCountForStatement($context)
: $this->getCountForSql($context);
};
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/Pdo/Pdo.php
================================================
registerConnection($connection);
$this->registerStatementPrototype(($statementPrototype) ?: new Statement());
$this->registerResultPrototype(($resultPrototype) ?: new Result());
if (is_array($features)) {
foreach ($features as $name => $feature) {
$this->addFeature($name, $feature);
}
} elseif ($features instanceof AbstractFeature) {
$this->addFeature($features->getName(), $features);
} elseif ($features === self::FEATURES_DEFAULT) {
$this->setupDefaultFeatures();
}
}
/**
* @param Profiler\ProfilerInterface $profiler
* @return self Provides a fluent interface
*/
public function setProfiler(Profiler\ProfilerInterface $profiler)
{
$this->profiler = $profiler;
if ($this->connection instanceof Profiler\ProfilerAwareInterface) {
$this->connection->setProfiler($profiler);
}
if ($this->statementPrototype instanceof Profiler\ProfilerAwareInterface) {
$this->statementPrototype->setProfiler($profiler);
}
return $this;
}
/**
* @return null|Profiler\ProfilerInterface
*/
public function getProfiler()
{
return $this->profiler;
}
/**
* Register connection
*
* @param Connection $connection
* @return self Provides a fluent interface
*/
public function registerConnection(Connection $connection)
{
$this->connection = $connection;
$this->connection->setDriver($this);
return $this;
}
/**
* Register statement prototype
*
* @param Statement $statementPrototype
*/
public function registerStatementPrototype(Statement $statementPrototype)
{
$this->statementPrototype = $statementPrototype;
$this->statementPrototype->setDriver($this);
}
/**
* Register result prototype
*
* @param Result $resultPrototype
*/
public function registerResultPrototype(Result $resultPrototype)
{
$this->resultPrototype = $resultPrototype;
}
/**
* Add feature
*
* @param string $name
* @param AbstractFeature $feature
* @return self Provides a fluent interface
*/
public function addFeature($name, $feature)
{
if ($feature instanceof AbstractFeature) {
$name = $feature->getName(); // overwrite the name, just in case
$feature->setDriver($this);
}
$this->features[$name] = $feature;
return $this;
}
/**
* Setup the default features for Pdo
*
* @return self Provides a fluent interface
*/
public function setupDefaultFeatures()
{
$driverName = $this->connection->getDriverName();
if ($driverName == 'sqlite') {
$this->addFeature(null, new Feature\SqliteRowCounter);
} elseif ($driverName == 'oci') {
$this->addFeature(null, new Feature\OracleRowCounter);
}
return $this;
}
/**
* Get feature
*
* @param $name
* @return AbstractFeature|false
*/
public function getFeature($name)
{
if (isset($this->features[$name])) {
return $this->features[$name];
}
return false;
}
/**
* Get database platform name
*
* @param string $nameFormat
* @return string
*/
public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE)
{
$name = $this->getConnection()->getDriverName();
if ($nameFormat == self::NAME_FORMAT_CAMELCASE) {
switch ($name) {
case 'pgsql':
return 'Postgresql';
case 'oci':
return 'Oracle';
case 'dblib':
case 'sqlsrv':
return 'SqlServer';
default:
return ucfirst($name);
}
} else {
switch ($name) {
case 'sqlite':
return 'SQLite';
case 'mysql':
return 'MySQL';
case 'pgsql':
return 'PostgreSQL';
case 'oci':
return 'Oracle';
case 'dblib':
case 'sqlsrv':
return 'SQLServer';
default:
return ucfirst($name);
}
}
}
/**
* Check environment
*/
public function checkEnvironment()
{
if (! extension_loaded('PDO')) {
throw new Exception\RuntimeException(
'The PDO extension is required for this adapter but the extension is not loaded'
);
}
}
/**
* @return Connection
*/
public function getConnection()
{
return $this->connection;
}
/**
* @param string|PDOStatement $sqlOrResource
* @return Statement
*/
public function createStatement($sqlOrResource = null)
{
$statement = clone $this->statementPrototype;
if ($sqlOrResource instanceof PDOStatement) {
$statement->setResource($sqlOrResource);
} else {
if (is_string($sqlOrResource)) {
$statement->setSql($sqlOrResource);
}
if (! $this->connection->isConnected()) {
$this->connection->connect();
}
$statement->initialize($this->connection->getResource());
}
return $statement;
}
/**
* @param resource $resource
* @param mixed $context
* @return Result
*/
public function createResult($resource, $context = null)
{
$result = clone $this->resultPrototype;
$rowCount = null;
// special feature, sqlite PDO counter
if ($this->connection->getDriverName() == 'sqlite'
&& ($sqliteRowCounter = $this->getFeature('SqliteRowCounter'))
&& $resource->columnCount() > 0) {
$rowCount = $sqliteRowCounter->getRowCountClosure($context);
}
// special feature, oracle PDO counter
if ($this->connection->getDriverName() == 'oci'
&& ($oracleRowCounter = $this->getFeature('OracleRowCounter'))
&& $resource->columnCount() > 0) {
$rowCount = $oracleRowCounter->getRowCountClosure($context);
}
$result->initialize($resource, $this->connection->getLastGeneratedValue(), $rowCount);
return $result;
}
/**
* @return string
*/
public function getPrepareType()
{
return self::PARAMETERIZATION_NAMED;
}
/**
* @param string $name
* @param string|null $type
* @return string
*/
public function formatParameterName($name, $type = null)
{
if ($type === null && ! is_numeric($name) || $type == self::PARAMETERIZATION_NAMED) {
$name = ltrim($name, ':');
// @see https://bugs.php.net/bug.php?id=43130
if (preg_match('/[^a-zA-Z0-9_]/', $name)) {
throw new Exception\RuntimeException(sprintf(
'The PDO param %s contains invalid characters.'
. ' Only alphabetic characters, digits, and underscores (_)'
. ' are allowed.',
$name
));
}
return ':' . $name;
}
return '?';
}
/**
* @param string|null $name
* @return string|null|false
*/
public function getLastGeneratedValue($name = null)
{
return $this->connection->getLastGeneratedValue($name);
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/Pdo/Result.php
================================================
resource = $resource;
$this->generatedValue = $generatedValue;
$this->rowCount = $rowCount;
return $this;
}
/**
* @return null
*/
public function buffer()
{
return;
}
/**
* @return bool|null
*/
public function isBuffered()
{
return false;
}
/**
* @param int $fetchMode
* @throws Exception\InvalidArgumentException on invalid fetch mode
*/
public function setFetchMode($fetchMode)
{
if ($fetchMode < 1 || $fetchMode > 10) {
throw new Exception\InvalidArgumentException(
'The fetch mode must be one of the PDO::FETCH_* constants.'
);
}
$this->fetchMode = (int) $fetchMode;
}
/**
* @return int
*/
public function getFetchMode()
{
return $this->fetchMode;
}
/**
* Get resource
*
* @return mixed
*/
public function getResource()
{
return $this->resource;
}
/**
* Get the data
* @return mixed
*/
#[ReturnTypeWillChange] public function current()
{
if ($this->currentComplete) {
return $this->currentData;
}
$this->currentData = $this->resource->fetch($this->fetchMode);
$this->currentComplete = true;
return $this->currentData;
}
/**
* Next
*
* @return mixed
*/
#[ReturnTypeWillChange] public function next()
{
$this->currentData = $this->resource->fetch($this->fetchMode);
$this->currentComplete = true;
$this->position++;
return $this->currentData;
}
/**
* Key
*
* @return mixed
*/
#[ReturnTypeWillChange] public function key()
{
return $this->position;
}
/**
* @throws Exception\RuntimeException
* @return void
*/
#[ReturnTypeWillChange] public function rewind()
{
if ($this->statementMode == self::STATEMENT_MODE_FORWARD && $this->position > 0) {
throw new Exception\RuntimeException(
'This result is a forward only result set, calling rewind() after moving forward is not supported'
);
}
$this->currentData = $this->resource->fetch($this->fetchMode);
$this->currentComplete = true;
$this->position = 0;
}
/**
* Valid
*
* @return bool
*/
#[ReturnTypeWillChange] public function valid()
{
return ($this->currentData !== false);
}
/**
* Count
*
* @return int
*/
#[ReturnTypeWillChange] public function count()
{
if (is_int($this->rowCount)) {
return $this->rowCount;
}
if ($this->rowCount instanceof \Closure) {
$this->rowCount = (int) call_user_func($this->rowCount);
} else {
$this->rowCount = $this->resource->rowCount();
}
return $this->rowCount;
}
/**
* @return int
*/
public function getFieldCount()
{
return $this->resource->columnCount();
}
/**
* Is query result
*
* @return bool
*/
public function isQueryResult()
{
return ($this->resource->columnCount() > 0);
}
/**
* Get affected rows
*
* @return int
*/
public function getAffectedRows()
{
return $this->resource->rowCount();
}
/**
* @return mixed|null
*/
public function getGeneratedValue()
{
return $this->generatedValue;
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/Pdo/Statement.php
================================================
driver = $driver;
return $this;
}
/**
* @param Profiler\ProfilerInterface $profiler
* @return self Provides a fluent interface
*/
public function setProfiler(Profiler\ProfilerInterface $profiler)
{
$this->profiler = $profiler;
return $this;
}
/**
* @return null|Profiler\ProfilerInterface
*/
public function getProfiler()
{
return $this->profiler;
}
/**
* Initialize
*
* @param \PDO $connectionResource
* @return self Provides a fluent interface
*/
public function initialize(\PDO $connectionResource)
{
$this->pdo = $connectionResource;
return $this;
}
/**
* Set resource
*
* @param \PDOStatement $pdoStatement
* @return self Provides a fluent interface
*/
public function setResource(\PDOStatement $pdoStatement)
{
$this->resource = $pdoStatement;
return $this;
}
/**
* Get resource
*
* @return mixed
*/
public function getResource()
{
return $this->resource;
}
/**
* Set sql
*
* @param string $sql
* @return self Provides a fluent interface
*/
public function setSql($sql)
{
$this->sql = $sql;
return $this;
}
/**
* Get sql
*
* @return string
*/
public function getSql()
{
return $this->sql;
}
/**
* @param ParameterContainer $parameterContainer
* @return self Provides a fluent interface
*/
public function setParameterContainer(ParameterContainer $parameterContainer)
{
$this->parameterContainer = $parameterContainer;
return $this;
}
/**
* @return ParameterContainer
*/
public function getParameterContainer()
{
return $this->parameterContainer;
}
/**
* @param string $sql
* @throws Exception\RuntimeException
*/
public function prepare($sql = null)
{
if ($this->isPrepared) {
throw new Exception\RuntimeException('This statement has been prepared already');
}
if ($sql === null) {
$sql = $this->sql;
}
$this->resource = $this->pdo->prepare($sql);
if ($this->resource === false) {
$error = $this->pdo->errorInfo();
throw new Exception\RuntimeException($error[2]);
}
$this->isPrepared = true;
}
/**
* @return bool
*/
public function isPrepared()
{
return $this->isPrepared;
}
/**
* @param null|array|ParameterContainer $parameters
* @throws Exception\InvalidQueryException
* @return Result
*/
public function execute($parameters = null)
{
if (! $this->isPrepared) {
$this->prepare();
}
/** START Standard ParameterContainer Merging Block */
if (! $this->parameterContainer instanceof ParameterContainer) {
if ($parameters instanceof ParameterContainer) {
$this->parameterContainer = $parameters;
$parameters = null;
} else {
$this->parameterContainer = new ParameterContainer();
}
}
if (is_array($parameters)) {
$this->parameterContainer->setFromArray($parameters);
}
if ($this->parameterContainer->count() > 0) {
$this->bindParametersFromContainer();
}
/** END Standard ParameterContainer Merging Block */
$this->profiler?->profilerStart($this);
try {
$this->resource->execute();
} catch (\PDOException $e) {
$this->profiler?->profilerFinish();
throw new Exception\InvalidQueryException(
'Statement could not be executed (' . implode(' - ', $this->resource->errorInfo()) . ')',
null,
$e
);
}
$this->profiler?->profilerFinish();
$result = $this->driver->createResult($this->resource, $this);
return $result;
}
/**
* Bind parameters from container
*/
protected function bindParametersFromContainer()
{
if ($this->parametersBound) {
return;
}
$parameters = $this->parameterContainer->getNamedArray();
foreach ($parameters as $name => &$value) {
if (is_bool($value)) {
$type = \PDO::PARAM_BOOL;
} else {
$type = \PDO::PARAM_STR;
}
if ($this->parameterContainer->offsetHasErrata($name)) {
switch ($this->parameterContainer->offsetGetErrata($name)) {
case ParameterContainer::TYPE_INTEGER:
$type = \PDO::PARAM_INT;
break;
case ParameterContainer::TYPE_NULL:
$type = \PDO::PARAM_NULL;
break;
case ParameterContainer::TYPE_LOB:
$type = \PDO::PARAM_LOB;
break;
}
}
// parameter is named or positional, value is reference
$parameter = is_int($name) ? ($name + 1) : $this->driver->formatParameterName($name);
$this->resource->bindParam($parameter, $value, $type);
}
}
/**
* Perform a deep clone
* @return Statement A cloned statement
*/
public function __clone()
{
$this->isPrepared = false;
$this->parametersBound = false;
$this->resource = null;
if ($this->parameterContainer) {
$this->parameterContainer = clone $this->parameterContainer;
}
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/Pgsql/Connection.php
================================================
setConnectionParameters($connectionInfo);
} elseif (is_resource($connectionInfo)) {
$this->setResource($connectionInfo);
}
}
/**
* Set resource
*
* @param resource $resource
* @return self Provides a fluent interface
*/
public function setResource($resource)
{
$this->resource = $resource;
return $this;
}
/**
* Set driver
*
* @param Pgsql $driver
* @return self Provides a fluent interface
*/
public function setDriver(Pgsql $driver)
{
$this->driver = $driver;
return $this;
}
/**
* @param int|null $type
* @return self Provides a fluent interface
*/
public function setType($type)
{
$invalidConectionType = ($type !== PGSQL_CONNECT_FORCE_NEW);
// Compatibility with PHP < 5.6
if ($invalidConectionType && defined('PGSQL_CONNECT_ASYNC')) {
$invalidConectionType = ($type !== PGSQL_CONNECT_ASYNC);
}
if ($invalidConectionType) {
throw new Exception\InvalidArgumentException(
'Connection type is not valid. (See: https://php.net/manual/en/function.pg-connect.php)'
);
}
$this->type = $type;
return $this;
}
/**
* {@inheritDoc}
*
* @return null|string
*/
public function getCurrentSchema()
{
if (! $this->isConnected()) {
$this->connect();
}
$result = pg_query($this->resource, 'SELECT CURRENT_SCHEMA AS "currentschema"');
if (! $result) {
return;
}
return pg_fetch_result($result, 0, 'currentschema');
}
/**
* {@inheritDoc}
*
* @throws Exception\RuntimeException on failure
*/
public function connect()
{
if (is_resource($this->resource)) {
return $this;
}
$connection = $this->getConnectionString();
set_error_handler(function ($number, $string) {
throw new Exception\RuntimeException(
__METHOD__ . ': Unable to connect to database',
null,
new Exception\ErrorException($string, $number)
);
});
$this->resource = pg_connect($connection);
restore_error_handler();
if ($this->resource === false) {
throw new Exception\RuntimeException(sprintf(
'%s: Unable to connect to database',
__METHOD__
));
}
$p = $this->connectionParameters;
if (! empty($p['charset'])) {
if (-1 === pg_set_client_encoding($this->resource, $p['charset'])) {
throw new Exception\RuntimeException(sprintf(
"%s: Unable to set client encoding '%s'",
__METHOD__,
$p['charset']
));
}
}
return $this;
}
/**
* {@inheritDoc}
*/
public function isConnected()
{
return (is_resource($this->resource));
}
/**
* {@inheritDoc}
*/
public function disconnect()
{
pg_close($this->resource);
return $this;
}
/**
* {@inheritDoc}
*/
public function beginTransaction()
{
if ($this->inTransaction()) {
throw new Exception\RuntimeException('Nested transactions are not supported');
}
if (! $this->isConnected()) {
$this->connect();
}
pg_query($this->resource, 'BEGIN');
$this->inTransaction = true;
return $this;
}
/**
* {@inheritDoc}
*/
public function commit()
{
if (! $this->isConnected()) {
$this->connect();
}
if (! $this->inTransaction()) {
return; // We ignore attempts to commit non-existing transaction
}
pg_query($this->resource, 'COMMIT');
$this->inTransaction = false;
return $this;
}
/**
* {@inheritDoc}
*/
public function rollback()
{
if (! $this->isConnected()) {
throw new Exception\RuntimeException('Must be connected before you can rollback');
}
if (! $this->inTransaction()) {
throw new Exception\RuntimeException('Must call beginTransaction() before you can rollback');
}
pg_query($this->resource, 'ROLLBACK');
$this->inTransaction = false;
return $this;
}
/**
* {@inheritDoc}
*
* @throws Exception\InvalidQueryException
* @return resource|\Zend\Db\ResultSet\ResultSetInterface
*/
public function execute($sql)
{
if (! $this->isConnected()) {
$this->connect();
}
$this->profiler?->profilerStart($sql);
$resultResource = pg_query($this->resource, $sql);
$this->profiler?->profilerFinish($sql);
// if the returnValue is something other than a pg result resource, bypass wrapping it
if ($resultResource === false) {
throw new Exception\InvalidQueryException(pg_errormessage());
}
$resultPrototype = $this->driver->createResult(($resultResource === true) ? $this->resource : $resultResource);
return $resultPrototype;
}
/**
* {@inheritDoc}
*
* @return string
*/
public function getLastGeneratedValue($name = null)
{
if ($name === null) {
return;
}
$result = pg_query(
$this->resource,
'SELECT CURRVAL(\'' . str_replace('\'', '\\\'', $name) . '\') as "currval"'
);
return pg_fetch_result($result, 0, 'currval');
}
/**
* Get Connection String
*
* @return string
*/
private function getConnectionString()
{
// localize
$p = $this->connectionParameters;
// given a list of key names, test for existence in $p
$findParameterValue = function (array $names) use ($p) {
foreach ($names as $name) {
if (isset($p[$name])) {
return $p[$name];
}
}
return;
};
$connectionParameters = [
'host' => $findParameterValue(['hostname', 'host']),
'user' => $findParameterValue(['username', 'user']),
'password' => $findParameterValue(['password', 'passwd', 'pw']),
'dbname' => $findParameterValue(['database', 'dbname', 'db', 'schema']),
'port' => isset($p['port']) ? (int) $p['port'] : null,
'socket' => $p['socket'] ?? null,
];
return urldecode(http_build_query(array_filter($connectionParameters), null, ' '));
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/Pgsql/Pgsql.php
================================================
false
];
/**
* Constructor
*
* @param array|Connection|resource $connection
* @param Statement|null $statementPrototype
* @param Result|null $resultPrototype
*/
public function __construct(
$connection,
?Statement $statementPrototype = null,
?Result $resultPrototype = null
) {
if (! $connection instanceof Connection) {
$connection = new Connection($connection);
}
$this->registerConnection($connection);
$this->registerStatementPrototype(($statementPrototype) ?: new Statement());
$this->registerResultPrototype(($resultPrototype) ?: new Result());
}
/**
* @param Profiler\ProfilerInterface $profiler
* @return self Provides a fluent interface
*/
public function setProfiler(Profiler\ProfilerInterface $profiler)
{
$this->profiler = $profiler;
if ($this->connection instanceof Profiler\ProfilerAwareInterface) {
$this->connection->setProfiler($profiler);
}
if ($this->statementPrototype instanceof Profiler\ProfilerAwareInterface) {
$this->statementPrototype->setProfiler($profiler);
}
return $this;
}
/**
* @return null|Profiler\ProfilerInterface
*/
public function getProfiler()
{
return $this->profiler;
}
/**
* Register connection
*
* @param Connection $connection
* @return self Provides a fluent interface
*/
public function registerConnection(Connection $connection)
{
$this->connection = $connection;
$this->connection->setDriver($this);
return $this;
}
/**
* Register statement prototype
*
* @param Statement $statement
* @return self Provides a fluent interface
*/
public function registerStatementPrototype(Statement $statement)
{
$this->statementPrototype = $statement;
$this->statementPrototype->setDriver($this); // needs access to driver to createResult()
return $this;
}
/**
* Register result prototype
*
* @param Result $result
* @return self Provides a fluent interface
*/
public function registerResultPrototype(Result $result)
{
$this->resultPrototype = $result;
return $this;
}
/**
* Get database platform name
*
* @param string $nameFormat
* @return string
*/
public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE)
{
if ($nameFormat == self::NAME_FORMAT_CAMELCASE) {
return 'Postgresql';
}
return 'PostgreSQL';
}
/**
* Check environment
*
* @throws Exception\RuntimeException
* @return bool
*/
public function checkEnvironment()
{
if (! extension_loaded('pgsql')) {
throw new Exception\RuntimeException(
'The PostgreSQL (pgsql) extension is required for this adapter but the extension is not loaded'
);
}
}
/**
* Get connection
*
* @return Connection
*/
public function getConnection()
{
return $this->connection;
}
/**
* Create statement
*
* @param string|null $sqlOrResource
* @return Statement
*/
public function createStatement($sqlOrResource = null)
{
$statement = clone $this->statementPrototype;
if (is_string($sqlOrResource)) {
$statement->setSql($sqlOrResource);
}
if (! $this->connection->isConnected()) {
$this->connection->connect();
}
$statement->initialize($this->connection->getResource());
return $statement;
}
/**
* Create result
*
* @param resource $resource
* @return Result
*/
public function createResult($resource)
{
$result = clone $this->resultPrototype;
$result->initialize($resource, $this->connection->getLastGeneratedValue());
return $result;
}
/**
* Get prepare Type
*
* @return string
*/
public function getPrepareType()
{
return self::PARAMETERIZATION_POSITIONAL;
}
/**
* Format parameter name
*
* @param string $name
* @param mixed $type
* @return string
*/
public function formatParameterName($name, $type = null)
{
return '$#';
}
/**
* Get last generated value
*
* @param string $name
* @return mixed
*/
public function getLastGeneratedValue($name = null)
{
return $this->connection->getLastGeneratedValue($name);
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/Pgsql/Result.php
================================================
resource = $resource;
$this->count = pg_num_rows($this->resource);
$this->generatedValue = $generatedValue;
}
/**
* Current
*
* @return array|bool|mixed
*/
#[ReturnTypeWillChange] public function current()
{
if ($this->count === 0) {
return false;
}
return pg_fetch_assoc($this->resource, $this->position);
}
/**
* Next
*
* @return void
*/
#[ReturnTypeWillChange] public function next()
{
$this->position++;
}
/**
* Key
*
* @return int|mixed
*/
#[ReturnTypeWillChange] public function key()
{
return $this->position;
}
/**
* Valid
*
* @return bool
*/
#[ReturnTypeWillChange] public function valid()
{
return ($this->position < $this->count);
}
/**
* Rewind
*
* @return void
*/
#[ReturnTypeWillChange] public function rewind()
{
$this->position = 0;
}
/**
* Buffer
*
* @return null
*/
public function buffer()
{
return;
}
/**
* Is buffered
*
* @return false
*/
public function isBuffered()
{
return false;
}
/**
* Is query result
*
* @return bool
*/
public function isQueryResult()
{
return (pg_num_fields($this->resource) > 0);
}
/**
* Get affected rows
*
* @return int
*/
public function getAffectedRows()
{
return pg_affected_rows($this->resource);
}
/**
* Get generated value
*
* @return mixed|null
*/
public function getGeneratedValue()
{
return $this->generatedValue;
}
/**
* Get resource
*/
public function getResource()
{
// TODO: Implement getResource() method.
}
/**
* Count
*
* (PHP 5 >= 5.1.0)
* Count elements of an object
* @link http://php.net/manual/en/countable.count.php
* @return int The custom count as an integer.
*
*
* The return value is cast to an integer.
*/
#[ReturnTypeWillChange] public function count()
{
return $this->count;
}
/**
* Get field count
*
* @return int
*/
public function getFieldCount()
{
return pg_num_fields($this->resource);
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/Pgsql/Statement.php
================================================
driver = $driver;
return $this;
}
/**
* @param Profiler\ProfilerInterface $profiler
* @return self Provides a fluent interface
*/
public function setProfiler(Profiler\ProfilerInterface $profiler)
{
$this->profiler = $profiler;
return $this;
}
/**
* @return null|Profiler\ProfilerInterface
*/
public function getProfiler()
{
return $this->profiler;
}
/**
* Initialize
*
* @param resource $pgsql
* @return void
* @throws Exception\RuntimeException for invalid or missing postgresql connection
*/
public function initialize($pgsql)
{
if (! is_resource($pgsql) || get_resource_type($pgsql) !== 'pgsql link') {
throw new Exception\RuntimeException(sprintf(
'%s: Invalid or missing postgresql connection; received "%s"',
__METHOD__,
get_resource_type($pgsql)
));
}
$this->pgsql = $pgsql;
}
/**
* Get resource
*
* @return resource
*/
public function getResource()
{
// TODO: Implement getResource() method.
}
/**
* Set sql
*
* @param string $sql
* @return self Provides a fluent interface
*/
public function setSql($sql)
{
$this->sql = $sql;
return $this;
}
/**
* Get sql
*
* @return string
*/
public function getSql()
{
return $this->sql;
}
/**
* Set parameter container
*
* @param ParameterContainer $parameterContainer
* @return self Provides a fluent interface
*/
public function setParameterContainer(ParameterContainer $parameterContainer)
{
$this->parameterContainer = $parameterContainer;
return $this;
}
/**
* Get parameter container
*
* @return ParameterContainer
*/
public function getParameterContainer()
{
return $this->parameterContainer;
}
/**
* Prepare
*
* @param string $sql
*/
public function prepare($sql = null)
{
$sql = ($sql) ?: $this->sql;
$pCount = 1;
$sql = preg_replace_callback(
'#\$\##',
function () use (&$pCount) {
return '$' . $pCount++;
},
$sql
);
$this->sql = $sql;
$this->statementName = 'statement' . ++static::$statementIndex;
$this->resource = pg_prepare($this->pgsql, $this->statementName, $sql);
}
/**
* Is prepared
*
* @return bool
*/
public function isPrepared()
{
return isset($this->resource);
}
/**
* Execute
*
* @param null|array|ParameterContainer $parameters
* @throws Exception\InvalidQueryException
* @return Result
*/
public function execute($parameters = null)
{
if (! $this->isPrepared()) {
$this->prepare();
}
/** START Standard ParameterContainer Merging Block */
if (! $this->parameterContainer instanceof ParameterContainer) {
if ($parameters instanceof ParameterContainer) {
$this->parameterContainer = $parameters;
$parameters = null;
} else {
$this->parameterContainer = new ParameterContainer();
}
}
if (is_array($parameters)) {
$this->parameterContainer->setFromArray($parameters);
}
if ($this->parameterContainer->count() > 0) {
$parameters = $this->parameterContainer->getPositionalArray();
}
/** END Standard ParameterContainer Merging Block */
$this->profiler?->profilerStart($this);
$resultResource = pg_execute($this->pgsql, $this->statementName, (array) $parameters);
$this->profiler?->profilerFinish();
if ($resultResource === false) {
throw new Exception\InvalidQueryException(pg_last_error());
}
$result = $this->driver->createResult($resultResource);
return $result;
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/ResultInterface.php
================================================
setConnectionParameters($connectionInfo);
} elseif (is_resource($connectionInfo)) {
$this->setResource($connectionInfo);
} else {
throw new Exception\InvalidArgumentException('$connection must be an array of parameters or a resource');
}
}
/**
* Set driver
*
* @param Sqlsrv $driver
* @return self Provides a fluent interface
*/
public function setDriver(Sqlsrv $driver)
{
$this->driver = $driver;
return $this;
}
/**
* {@inheritDoc}
*/
public function getCurrentSchema()
{
if (! $this->isConnected()) {
$this->connect();
}
$result = sqlsrv_query($this->resource, 'SELECT SCHEMA_NAME()');
$r = sqlsrv_fetch_array($result);
return $r[0];
}
/**
* Set resource
*
* @param resource $resource
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function setResource($resource)
{
if (get_resource_type($resource) !== 'SQL Server Connection') {
throw new Exception\InvalidArgumentException('Resource provided was not of type SQL Server Connection');
}
$this->resource = $resource;
return $this;
}
/**
* {@inheritDoc}
*
* @throws Exception\RuntimeException
*/
public function connect()
{
if ($this->resource) {
return $this;
}
$serverName = '.';
$params = [
'ReturnDatesAsStrings' => true
];
foreach ($this->connectionParameters as $key => $value) {
switch (strtolower($key)) {
case 'hostname':
case 'servername':
$serverName = (string) $value;
break;
case 'username':
case 'uid':
$params['UID'] = (string) $value;
break;
case 'password':
case 'pwd':
$params['PWD'] = (string) $value;
break;
case 'database':
case 'dbname':
$params['Database'] = (string) $value;
break;
case 'charset':
$params['CharacterSet'] = (string) $value;
break;
case 'driver_options':
case 'options':
$params = array_merge($params, (array) $value);
break;
}
}
$this->resource = sqlsrv_connect($serverName, $params);
if (! $this->resource) {
throw new Exception\RuntimeException(
'Connect Error',
null,
new ErrorException(sqlsrv_errors())
);
}
return $this;
}
/**
* {@inheritDoc}
*/
public function isConnected()
{
return (is_resource($this->resource));
}
/**
* {@inheritDoc}
*/
public function disconnect()
{
sqlsrv_close($this->resource);
$this->resource = null;
}
/**
* {@inheritDoc}
*/
public function beginTransaction()
{
if (! $this->isConnected()) {
$this->connect();
}
if (sqlsrv_begin_transaction($this->resource) === false) {
throw new Exception\RuntimeException(
new ErrorException(sqlsrv_errors())
);
}
$this->inTransaction = true;
return $this;
}
/**
* {@inheritDoc}
*/
public function commit()
{
// http://msdn.microsoft.com/en-us/library/cc296194.aspx
if (! $this->isConnected()) {
$this->connect();
}
sqlsrv_commit($this->resource);
$this->inTransaction = false;
return $this;
}
/**
* {@inheritDoc}
*/
public function rollback()
{
// http://msdn.microsoft.com/en-us/library/cc296176.aspx
if (! $this->isConnected()) {
throw new Exception\RuntimeException('Must be connected before you can rollback.');
}
sqlsrv_rollback($this->resource);
$this->inTransaction = false;
return $this;
}
/**
* {@inheritDoc}
*
* @throws Exception\RuntimeException
*/
public function execute($sql)
{
if (! $this->isConnected()) {
$this->connect();
}
if (! $this->driver instanceof Sqlsrv) {
throw new Exception\RuntimeException('Connection is missing an instance of Sqlsrv');
}
$this->profiler?->profilerStart($sql);
$returnValue = sqlsrv_query($this->resource, $sql);
$this->profiler?->profilerFinish($sql);
// if the returnValue is something other than a Sqlsrv_result, bypass wrapping it
if ($returnValue === false) {
$errors = sqlsrv_errors();
// ignore general warnings
if ($errors[0]['SQLSTATE'] != '01000') {
throw new Exception\RuntimeException(
'An exception occurred while trying to execute the provided $sql',
null,
new ErrorException($errors)
);
}
}
$result = $this->driver->createResult($returnValue);
return $result;
}
/**
* Prepare
*
* @param string $sql
* @return string
*/
public function prepare($sql)
{
if (! $this->isConnected()) {
$this->connect();
}
$statement = $this->driver->createStatement($sql);
return $statement;
}
/**
* {@inheritDoc}
*
* @return mixed
*/
public function getLastGeneratedValue($name = null)
{
if (! $this->resource) {
$this->connect();
}
$sql = 'SELECT @@IDENTITY as Current_Identity';
$result = sqlsrv_query($this->resource, $sql);
$row = sqlsrv_fetch_array($result);
return $row['Current_Identity'];
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/Sqlsrv/Exception/ErrorException.php
================================================
errors = ($errors === false) ? sqlsrv_errors() : $errors;
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/Sqlsrv/Exception/ExceptionInterface.php
================================================
resource = $resource;
$this->generatedValue = $generatedValue;
return $this;
}
/**
* @return null
*/
public function buffer()
{
return;
}
/**
* @return bool
*/
public function isBuffered()
{
return false;
}
/**
* Get resource
*
* @return resource
*/
public function getResource()
{
return $this->resource;
}
/**
* Current
*
* @return mixed
*/
#[ReturnTypeWillChange] public function current()
{
if ($this->currentComplete) {
return $this->currentData;
}
$this->load();
return $this->currentData;
}
/**
* Next
*
* @return bool
*/
#[ReturnTypeWillChange] public function next()
{
$this->load();
return true;
}
/**
* Load
*
* @param int $row
* @return mixed
*/
protected function load($row = SQLSRV_SCROLL_NEXT)
{
$this->currentData = sqlsrv_fetch_array($this->resource, SQLSRV_FETCH_ASSOC, $row);
$this->currentComplete = true;
$this->position++;
return $this->currentData;
}
/**
* Key
*
* @return mixed
*/
#[ReturnTypeWillChange] public function key()
{
return $this->position;
}
/**
* Rewind
*
* @return bool
*/
#[ReturnTypeWillChange] public function rewind()
{
$this->position = 0;
$this->load(SQLSRV_SCROLL_FIRST);
return true;
}
/**
* Valid
*
* @return bool
*/
#[ReturnTypeWillChange] public function valid()
{
if ($this->currentComplete && $this->currentData) {
return true;
}
return $this->load();
}
/**
* Count
*
* @return int
*/
#[ReturnTypeWillChange] public function count()
{
return sqlsrv_num_rows($this->resource);
}
/**
* @return bool|int
*/
public function getFieldCount()
{
return sqlsrv_num_fields($this->resource);
}
/**
* Is query result
*
* @return bool
*/
public function isQueryResult()
{
if (is_bool($this->resource)) {
return false;
}
return (sqlsrv_num_fields($this->resource) > 0);
}
/**
* Get affected rows
*
* @return int
*/
public function getAffectedRows()
{
return sqlsrv_rows_affected($this->resource);
}
/**
* @return mixed|null
*/
public function getGeneratedValue()
{
return $this->generatedValue;
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/Sqlsrv/Sqlsrv.php
================================================
registerConnection($connection);
$this->registerStatementPrototype(($statementPrototype) ?: new Statement());
$this->registerResultPrototype(($resultPrototype) ?: new Result());
}
/**
* @param Profiler\ProfilerInterface $profiler
* @return self Provides a fluent interface
*/
public function setProfiler(Profiler\ProfilerInterface $profiler)
{
$this->profiler = $profiler;
if ($this->connection instanceof Profiler\ProfilerAwareInterface) {
$this->connection->setProfiler($profiler);
}
if ($this->statementPrototype instanceof Profiler\ProfilerAwareInterface) {
$this->statementPrototype->setProfiler($profiler);
}
return $this;
}
/**
* @return null|Profiler\ProfilerInterface
*/
public function getProfiler()
{
return $this->profiler;
}
/**
* Register connection
*
* @param Connection $connection
* @return self Provides a fluent interface
*/
public function registerConnection(Connection $connection)
{
$this->connection = $connection;
$this->connection->setDriver($this);
return $this;
}
/**
* Register statement prototype
*
* @param Statement $statementPrototype
* @return self Provides a fluent interface
*/
public function registerStatementPrototype(Statement $statementPrototype)
{
$this->statementPrototype = $statementPrototype;
$this->statementPrototype->setDriver($this);
return $this;
}
/**
* Register result prototype
*
* @param Result $resultPrototype
* @return self Provides a fluent interface
*/
public function registerResultPrototype(Result $resultPrototype)
{
$this->resultPrototype = $resultPrototype;
return $this;
}
/**
* Get database paltform name
*
* @param string $nameFormat
* @return string
*/
public function getDatabasePlatformName($nameFormat = self::NAME_FORMAT_CAMELCASE)
{
if ($nameFormat == self::NAME_FORMAT_CAMELCASE) {
return 'SqlServer';
}
return 'SQLServer';
}
/**
* Check environment
*
* @throws Exception\RuntimeException
* @return void
*/
public function checkEnvironment()
{
if (! extension_loaded('sqlsrv')) {
throw new Exception\RuntimeException(
'The Sqlsrv extension is required for this adapter but the extension is not loaded'
);
}
}
/**
* @return Connection
*/
public function getConnection()
{
return $this->connection;
}
/**
* @param string|resource $sqlOrResource
* @return Statement
*/
public function createStatement($sqlOrResource = null)
{
$statement = clone $this->statementPrototype;
if (is_resource($sqlOrResource)) {
$statement->initialize($sqlOrResource);
} else {
if (! $this->connection->isConnected()) {
$this->connection->connect();
}
$statement->initialize($this->connection->getResource());
if (is_string($sqlOrResource)) {
$statement->setSql($sqlOrResource);
} elseif ($sqlOrResource !== null) {
throw new Exception\InvalidArgumentException(
'createStatement() only accepts an SQL string or a Sqlsrv resource'
);
}
}
return $statement;
}
/**
* @param resource $resource
* @return Result
*/
public function createResult($resource)
{
$result = clone $this->resultPrototype;
$result->initialize($resource, $this->connection->getLastGeneratedValue());
return $result;
}
/**
* @return string
*/
public function getPrepareType()
{
return self::PARAMETERIZATION_POSITIONAL;
}
/**
* @param string $name
* @param mixed $type
* @return string
*/
public function formatParameterName($name, $type = null)
{
return '?';
}
/**
* @return mixed
*/
public function getLastGeneratedValue()
{
return $this->getConnection()->getLastGeneratedValue();
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/Sqlsrv/Statement.php
================================================
driver = $driver;
return $this;
}
/**
* @param Profiler\ProfilerInterface $profiler
* @return self Provides a fluent interface
*/
public function setProfiler(Profiler\ProfilerInterface $profiler)
{
$this->profiler = $profiler;
return $this;
}
/**
* @return null|Profiler\ProfilerInterface
*/
public function getProfiler()
{
return $this->profiler;
}
/**
*
* One of two resource types will be provided here:
* a) "SQL Server Connection" when a prepared statement needs to still be produced
* b) "SQL Server Statement" when a prepared statement has been already produced
* (there will need to already be a bound param set if it applies to this query)
*
* @param resource $resource
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function initialize($resource)
{
$resourceType = get_resource_type($resource);
if ($resourceType == 'SQL Server Connection') {
$this->sqlsrv = $resource;
} elseif ($resourceType == 'SQL Server Statement') {
$this->resource = $resource;
$this->isPrepared = true;
} else {
throw new Exception\InvalidArgumentException('Invalid resource provided to ' . __CLASS__);
}
return $this;
}
/**
* Set parameter container
*
* @param ParameterContainer $parameterContainer
* @return self Provides a fluent interface
*/
public function setParameterContainer(ParameterContainer $parameterContainer)
{
$this->parameterContainer = $parameterContainer;
return $this;
}
/**
* @return ParameterContainer
*/
public function getParameterContainer()
{
return $this->parameterContainer;
}
/**
* @param $resource
* @return self Provides a fluent interface
*/
public function setResource($resource)
{
$this->resource = $resource;
return $this;
}
/**
* Get resource
*
* @return resource
*/
public function getResource()
{
return $this->resource;
}
/**
* @param string $sql
* @return self Provides a fluent interface
*/
public function setSql($sql)
{
$this->sql = $sql;
return $this;
}
/**
* Get sql
*
* @return string
*/
public function getSql()
{
return $this->sql;
}
/**
* @param string $sql
* @param array $options
* @return self Provides a fluent interface
* @throws Exception\RuntimeException
*/
public function prepare($sql = null, array $options = [])
{
if ($this->isPrepared) {
throw new Exception\RuntimeException('Already prepared');
}
$sql = ($sql) ?: $this->sql;
$options = ($options) ?: $this->prepareOptions;
$pRef = &$this->parameterReferences;
for ($position = 0, $count = substr_count($sql, '?'); $position < $count; $position++) {
if (! isset($this->prepareParams[$position])) {
$pRef[$position] = [&$this->parameterReferenceValues[$position], SQLSRV_PARAM_IN, null, null];
} else {
$pRef[$position] = &$this->prepareParams[$position];
}
}
$this->resource = sqlsrv_prepare($this->sqlsrv, $sql, $pRef, $options);
$this->isPrepared = true;
return $this;
}
/**
* @return bool
*/
public function isPrepared()
{
return $this->isPrepared;
}
/**
* Execute
*
* @param null|array|ParameterContainer $parameters
* @throws Exception\RuntimeException
* @return Result
*/
public function execute($parameters = null)
{
/** END Standard ParameterContainer Merging Block */
if (! $this->isPrepared) {
$this->prepare();
}
/** START Standard ParameterContainer Merging Block */
if (! $this->parameterContainer instanceof ParameterContainer) {
if ($parameters instanceof ParameterContainer) {
$this->parameterContainer = $parameters;
$parameters = null;
} else {
$this->parameterContainer = new ParameterContainer();
}
}
if (is_array($parameters)) {
$this->parameterContainer->setFromArray($parameters);
}
if ($this->parameterContainer->count() > 0) {
$this->bindParametersFromContainer();
}
$this->profiler?->profilerStart($this);
$resultValue = sqlsrv_execute($this->resource);
$this->profiler?->profilerFinish();
if ($resultValue === false) {
$errors = sqlsrv_errors();
// ignore general warnings
if ($errors[0]['SQLSTATE'] != '01000') {
throw new Exception\RuntimeException($errors[0]['message']);
}
}
$result = $this->driver->createResult($this->resource);
return $result;
}
/**
* Bind parameters from container
*
*/
protected function bindParametersFromContainer()
{
$values = $this->parameterContainer->getPositionalArray();
$position = 0;
foreach ($values as $value) {
$this->parameterReferences[$position++][0] = $value;
}
}
/**
* @param array $prepareParams
*/
public function setPrepareParams(array $prepareParams)
{
$this->prepareParams = $prepareParams;
}
/**
* @param array $prepareOptions
*/
public function setPrepareOptions(array $prepareOptions)
{
$this->prepareOptions = $prepareOptions;
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Driver/StatementInterface.php
================================================
parameters = $parameters;
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Exception/InvalidQueryException.php
================================================
setFromArray($data);
}
}
/**
* Offset exists
*
* @param string $name
* @return bool
*/
#[ReturnTypeWillChange] public function offsetExists($name)
{
return (isset($this->data[$name]));
}
/**
* Offset get
*
* @param string $name
* @return mixed
*/
#[ReturnTypeWillChange] public function offsetGet($name)
{
return (isset($this->data[$name])) ? $this->data[$name] : null;
}
/**
* @param $name
* @param $from
*/
public function offsetSetReference($name, $from)
{
$this->data[$name] =& $this->data[$from];
}
/**
* Offset set
*
* @param string|int $name
* @param mixed $value
* @param mixed $errata
* @param mixed $maxLength
* @throws Exception\InvalidArgumentException
*/
#[ReturnTypeWillChange] public function offsetSet($name, $value, $errata = null, $maxLength = null)
{
$position = false;
// if integer, get name for this position
if (is_int($name)) {
if (isset($this->positions[$name])) {
$position = $name;
$name = $this->positions[$name];
} else {
$name = (string) $name;
}
} elseif (is_string($name)) {
// is a string:
$position = array_key_exists($name, $this->data);
} elseif ($name === null) {
$name = (string) count($this->data);
} else {
throw new Exception\InvalidArgumentException('Keys must be string, integer or null');
}
if ($position === false) {
$this->positions[] = $name;
}
$this->data[$name] = $value;
if ($errata) {
$this->offsetSetErrata($name, $errata);
}
if ($maxLength) {
$this->offsetSetMaxLength($name, $maxLength);
}
}
/**
* Offset unset
*
* @param string $name
* @return self Provides a fluent interface
*/
#[ReturnTypeWillChange] public function offsetUnset($name)
{
if (is_int($name) && isset($this->positions[$name])) {
$name = $this->positions[$name];
}
unset($this->data[$name]);
return $this;
}
/**
* Set from array
*
* @param array $data
* @return self Provides a fluent interface
*/
public function setFromArray(array $data)
{
foreach ($data as $n => $v) {
$this->offsetSet($n, $v);
}
return $this;
}
/**
* Offset set max length
*
* @param string|int $name
* @param mixed $maxLength
*/
public function offsetSetMaxLength($name, $maxLength)
{
if (is_int($name)) {
$name = $this->positions[$name];
}
$this->maxLength[$name] = $maxLength;
}
/**
* Offset get max length
*
* @param string|int $name
* @throws Exception\InvalidArgumentException
* @return mixed
*/
public function offsetGetMaxLength($name)
{
if (is_int($name)) {
$name = $this->positions[$name];
}
if (! array_key_exists($name, $this->data)) {
throw new Exception\InvalidArgumentException('Data does not exist for this name/position');
}
return $this->maxLength[$name];
}
/**
* Offset has max length
*
* @param string|int $name
* @return bool
*/
public function offsetHasMaxLength($name)
{
if (is_int($name)) {
$name = $this->positions[$name];
}
return (isset($this->maxLength[$name]));
}
/**
* Offset unset max length
*
* @param string|int $name
* @throws Exception\InvalidArgumentException
*/
public function offsetUnsetMaxLength($name)
{
if (is_int($name)) {
$name = $this->positions[$name];
}
if (! array_key_exists($name, $this->maxLength)) {
throw new Exception\InvalidArgumentException('Data does not exist for this name/position');
}
$this->maxLength[$name] = null;
}
/**
* Get max length iterator
*
* @return \ArrayIterator
*/
public function getMaxLengthIterator()
{
return new \ArrayIterator($this->maxLength);
}
/**
* Offset set errata
*
* @param string|int $name
* @param mixed $errata
*/
public function offsetSetErrata($name, $errata)
{
if (is_int($name)) {
$name = $this->positions[$name];
}
$this->errata[$name] = $errata;
}
/**
* Offset get errata
*
* @param string|int $name
* @throws Exception\InvalidArgumentException
* @return mixed
*/
public function offsetGetErrata($name)
{
if (is_int($name)) {
$name = $this->positions[$name];
}
if (! array_key_exists($name, $this->data)) {
throw new Exception\InvalidArgumentException('Data does not exist for this name/position');
}
return $this->errata[$name];
}
/**
* Offset has errata
*
* @param string|int $name
* @return bool
*/
public function offsetHasErrata($name)
{
if (is_int($name)) {
$name = $this->positions[$name];
}
return (isset($this->errata[$name]));
}
/**
* Offset unset errata
*
* @param string|int $name
* @throws Exception\InvalidArgumentException
*/
public function offsetUnsetErrata($name)
{
if (is_int($name)) {
$name = $this->positions[$name];
}
if (! array_key_exists($name, $this->errata)) {
throw new Exception\InvalidArgumentException('Data does not exist for this name/position');
}
$this->errata[$name] = null;
}
/**
* Get errata iterator
*
* @return \ArrayIterator
*/
public function getErrataIterator()
{
return new \ArrayIterator($this->errata);
}
/**
* getNamedArray
*
* @return array
*/
public function getNamedArray()
{
return $this->data;
}
/**
* getNamedArray
*
* @return array
*/
public function getPositionalArray()
{
return array_values($this->data);
}
/**
* count
*
* @return int
*/
#[ReturnTypeWillChange] public function count()
{
return count($this->data);
}
/**
* Current
*
* @return mixed
*/
#[ReturnTypeWillChange] public function current()
{
return current($this->data);
}
/**
* Next
*
* @return mixed
*/
#[ReturnTypeWillChange] public function next()
{
return next($this->data);
}
/**
* Key
*
* @return mixed
*/
#[ReturnTypeWillChange] public function key()
{
return key($this->data);
}
/**
* Valid
*
* @return bool
*/
#[ReturnTypeWillChange] public function valid()
{
return (current($this->data) !== false);
}
/**
* Rewind
*/
#[ReturnTypeWillChange] public function rewind()
{
reset($this->data);
}
/**
* @param array|ParameterContainer $parameters
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function merge($parameters)
{
if (! is_array($parameters) && ! $parameters instanceof ParameterContainer) {
throw new Exception\InvalidArgumentException(
'$parameters must be an array or an instance of ParameterContainer'
);
}
if (count($parameters) == 0) {
return $this;
}
if ($parameters instanceof ParameterContainer) {
$parameters = $parameters->getNamedArray();
}
foreach ($parameters as $key => $value) {
if (is_int($key)) {
$key = null;
}
$this->offsetSet($key, $value);
}
return $this;
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Platform/AbstractPlatform.php
================================================
quoteIdentifiers) {
return $identifier;
}
$safeWordsInt = ['*' => true, ' ' => true, '.' => true, 'as' => true];
foreach ($safeWords as $sWord) {
$safeWordsInt[strtolower($sWord)] = true;
}
$parts = preg_split(
$this->quoteIdentifierFragmentPattern,
$identifier,
-1,
PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY
);
$identifier = '';
foreach ($parts as $part) {
$identifier .= isset($safeWordsInt[strtolower($part)])
? $part
: $this->quoteIdentifier[0]
. str_replace($this->quoteIdentifier[0], $this->quoteIdentifierTo, $part)
. $this->quoteIdentifier[1];
}
return $identifier;
}
/**
* {@inheritDoc}
*/
public function quoteIdentifier($identifier)
{
if (! $this->quoteIdentifiers) {
return $identifier;
}
return $this->quoteIdentifier[0]
. str_replace($this->quoteIdentifier[0], $this->quoteIdentifierTo, $identifier)
. $this->quoteIdentifier[1];
}
/**
* {@inheritDoc}
*/
public function quoteIdentifierChain($identifierChain)
{
return '"' . implode('"."', (array) str_replace('"', '\\"', $identifierChain)) . '"';
}
/**
* {@inheritDoc}
*/
public function getQuoteIdentifierSymbol()
{
return $this->quoteIdentifier[0];
}
/**
* {@inheritDoc}
*/
public function getQuoteValueSymbol()
{
return '\'';
}
/**
* {@inheritDoc}
*/
public function quoteValue($value)
{
trigger_error(
'Attempting to quote a value in ' . get_class($this) .
' without extension/driver support can introduce security vulnerabilities in a production environment'
);
return '\'' . addcslashes((string) $value, "\x00\n\r\\'\"\x1a") . '\'';
}
/**
* {@inheritDoc}
*/
public function quoteTrustedValue($value)
{
return '\'' . addcslashes((string) $value, "\x00\n\r\\'\"\x1a") . '\'';
}
/**
* {@inheritDoc}
*/
public function quoteValueList($valueList)
{
return implode(', ', array_map([$this, 'quoteValue'], (array) $valueList));
}
/**
* {@inheritDoc}
*/
public function getIdentifierSeparator()
{
return '.';
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Platform/IbmDb2.php
================================================
quoteIdentifiers = false;
}
if (isset($options['identifier_separator'])) {
$this->identifierSeparator = $options['identifier_separator'];
}
}
/**
* {@inheritDoc}
*/
public function getName()
{
return 'IBM DB2';
}
/**
* {@inheritDoc}
*/
public function quoteIdentifierInFragment($identifier, array $safeWords = [])
{
if (! $this->quoteIdentifiers) {
return $identifier;
}
$safeWordsInt = ['*' => true, ' ' => true, '.' => true, 'as' => true];
foreach ($safeWords as $sWord) {
$safeWordsInt[strtolower($sWord)] = true;
}
$parts = preg_split(
'/([^0-9,a-z,A-Z$#_:])/i',
$identifier,
-1,
PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY
);
$identifier = '';
foreach ($parts as $part) {
$identifier .= isset($safeWordsInt[strtolower($part)])
? $part
: $this->quoteIdentifier[0]
. str_replace($this->quoteIdentifier[0], $this->quoteIdentifierTo, $part)
. $this->quoteIdentifier[1];
}
return $identifier;
}
/**
* {@inheritDoc}
*/
public function quoteIdentifierChain($identifierChain)
{
if ($this->quoteIdentifiers === false) {
if (is_array($identifierChain)) {
return implode($this->identifierSeparator, $identifierChain);
} else {
return $identifierChain;
}
}
$identifierChain = str_replace('"', '\\"', $identifierChain);
if (is_array($identifierChain)) {
$identifierChain = implode('"' . $this->identifierSeparator . '"', $identifierChain);
}
return '"' . $identifierChain . '"';
}
/**
* {@inheritDoc}
*/
public function quoteValue($value)
{
if (function_exists('db2_escape_string')) {
return '\'' . db2_escape_string($value) . '\'';
}
trigger_error(
'Attempting to quote a value in ' . __CLASS__ . ' without extension/driver support '
. 'can introduce security vulnerabilities in a production environment.'
);
return '\'' . str_replace("'", "''", $value) . '\'';
}
/**
* {@inheritDoc}
*/
public function quoteTrustedValue($value)
{
if (function_exists('db2_escape_string')) {
return '\'' . db2_escape_string($value) . '\'';
}
return '\'' . str_replace("'", "''", $value) . '\'';
}
/**
* {@inheritDoc}
*/
public function getIdentifierSeparator()
{
return $this->identifierSeparator;
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Platform/Mysql.php
================================================
setDriver($driver);
}
}
/**
* @param \Zend\Db\Adapter\Driver\Mysqli\Mysqli|\Zend\Db\Adapter\Driver\Pdo\Pdo|\mysqli|\PDO $driver
* @return self Provides a fluent interface
* @throws \Zend\Db\Adapter\Exception\InvalidArgumentException
*/
public function setDriver($driver)
{
// handle Zend\Db drivers
if ($driver instanceof Mysqli\Mysqli
|| ($driver instanceof Pdo\Pdo && $driver->getDatabasePlatformName() == 'Mysql')
|| ($driver instanceof \mysqli)
|| ($driver instanceof \PDO && $driver->getAttribute(\PDO::ATTR_DRIVER_NAME) == 'mysql')
) {
$this->resource = $driver;
return $this;
}
throw new Exception\InvalidArgumentException(
'$driver must be a Mysqli or Mysql PDO Zend\Db\Adapter\Driver, Mysqli instance or MySQL PDO instance'
);
}
/**
* {@inheritDoc}
*/
public function getName()
{
return 'MySQL';
}
/**
* {@inheritDoc}
*/
public function quoteIdentifierChain($identifierChain)
{
return '`' . implode('`.`', (array) str_replace('`', '``', $identifierChain)) . '`';
}
/**
* {@inheritDoc}
*/
public function quoteValue($value)
{
if ($this->resource instanceof DriverInterface) {
$this->resource = $this->resource->getConnection()->getResource();
}
if ($this->resource instanceof \mysqli) {
return '\'' . $this->resource->real_escape_string($value) . '\'';
}
if ($this->resource instanceof \PDO) {
return $this->resource->quote($value);
}
return parent::quoteValue($value);
}
/**
* {@inheritDoc}
*/
public function quoteTrustedValue($value)
{
if ($this->resource instanceof DriverInterface) {
$this->resource = $this->resource->getConnection()->getResource();
}
if ($this->resource instanceof \mysqli) {
return '\'' . $this->resource->real_escape_string($value) . '\'';
}
if ($this->resource instanceof \PDO) {
return $this->resource->quote($value);
}
return parent::quoteTrustedValue($value);
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Platform/Oracle.php
================================================
quoteIdentifiers = false;
}
if ($driver) {
$this->setDriver($driver);
}
}
/**
* @param Pdo|Oci8 $driver
* @return self Provides a fluent interface
* @throws InvalidArgumentException
*/
public function setDriver($driver)
{
if ($driver instanceof Oci8
|| ($driver instanceof Pdo && $driver->getDatabasePlatformName() == 'Oracle')
|| ($driver instanceof Pdo && $driver->getDatabasePlatformName() == 'Sqlite')
|| ($driver instanceof \oci8)
) {
$this->resource = $driver;
return $this;
}
throw new InvalidArgumentException(
'$driver must be a Oci8 or Oracle PDO Zend\Db\Adapter\Driver, '
. 'Oci8 instance, or Oci PDO instance'
);
}
/**
* @return null|Pdo|Oci8
*/
public function getDriver()
{
return $this->resource;
}
/**
* {@inheritDoc}
*/
public function getName()
{
return 'Oracle';
}
/**
* {@inheritDoc}
*/
public function quoteIdentifierChain($identifierChain)
{
if ($this->quoteIdentifiers === false) {
return implode('.', (array) $identifierChain);
}
return '"' . implode('"."', (array) str_replace('"', '\\"', $identifierChain)) . '"';
}
/**
* {@inheritDoc}
*/
public function quoteValue($value)
{
if ($this->resource instanceof DriverInterface) {
$this->resource = $this->resource->getConnection()->getResource();
}
if ($this->resource) {
if ($this->resource instanceof PDO) {
return $this->resource->quote($value);
}
if (get_resource_type($this->resource) == 'oci8 connection'
|| get_resource_type($this->resource) == 'oci8 persistent connection'
) {
return "'" . addcslashes(str_replace("'", "''", $value), "\x00\n\r\"\x1a") . "'";
}
}
trigger_error(
'Attempting to quote a value in ' . __CLASS__ . ' without extension/driver support '
. 'can introduce security vulnerabilities in a production environment.'
);
return "'" . addcslashes(str_replace("'", "''", $value), "\x00\n\r\"\x1a") . "'";
}
/**
* {@inheritDoc}
*/
public function quoteTrustedValue($value)
{
return "'" . addcslashes(str_replace('\'', '\'\'', $value), "\x00\n\r\"\x1a") . "'";
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Platform/PlatformInterface.php
================================================
setDriver($driver);
}
}
/**
* @param \Zend\Db\Adapter\Driver\Pgsql\Pgsql|\Zend\Db\Adapter\Driver\Pdo\Pdo|resource|\PDO $driver
* @return self Provides a fluent interface
* @throws \Zend\Db\Adapter\Exception\InvalidArgumentException
*/
public function setDriver($driver)
{
if ($driver instanceof Pgsql\Pgsql
|| ($driver instanceof Pdo\Pdo && $driver->getDatabasePlatformName() == 'Postgresql')
|| (is_resource($driver) && (in_array(get_resource_type($driver), ['pgsql link', 'pgsql link persistent'])))
|| ($driver instanceof \PDO && $driver->getAttribute(\PDO::ATTR_DRIVER_NAME) == 'pgsql')
) {
$this->resource = $driver;
return $this;
}
throw new Exception\InvalidArgumentException(
'$driver must be a Pgsql or Postgresql PDO Zend\Db\Adapter\Driver, pgsql link resource or Postgresql PDO '
. 'instance'
);
}
/**
* {@inheritDoc}
*/
public function getName()
{
return 'PostgreSQL';
}
/**
* {@inheritDoc}
*/
public function quoteIdentifierChain($identifierChain)
{
return '"' . implode('"."', (array) str_replace('"', '""', $identifierChain)) . '"';
}
/**
* {@inheritDoc}
*/
public function quoteValue($value)
{
if ($this->resource instanceof DriverInterface) {
$this->resource = $this->resource->getConnection()->getResource();
}
if (is_resource($this->resource)) {
return '\'' . pg_escape_string($this->resource, $value) . '\'';
}
if ($this->resource instanceof \PDO) {
return $this->resource->quote($value);
}
return 'E' . parent::quoteValue($value);
}
/**
* {@inheritDoc}
*/
public function quoteTrustedValue($value)
{
if ($this->resource instanceof DriverInterface) {
$this->resource = $this->resource->getConnection()->getResource();
}
if (is_resource($this->resource)) {
return '\'' . pg_escape_string($this->resource, $value) . '\'';
}
if ($this->resource instanceof \PDO) {
return $this->resource->quote($value);
}
return 'E' . parent::quoteTrustedValue($value);
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Platform/Sql92.php
================================================
setDriver($driver);
}
}
/**
* @param \Zend\Db\Adapter\Driver\Sqlsrv\Sqlsrv|\Zend\Db\Adapter\Driver\Pdo\Pdo|resource|\PDO $driver
* @return self Provides a fluent interface
* @throws \Zend\Db\Adapter\Exception\InvalidArgumentException
*/
public function setDriver($driver)
{
// handle Zend\Db drivers
if (($driver instanceof Pdo\Pdo && in_array($driver->getDatabasePlatformName(), ['SqlServer', 'Dblib']))
|| ($driver instanceof \PDO && in_array($driver->getAttribute(\PDO::ATTR_DRIVER_NAME), ['sqlsrv', 'dblib']))
) {
$this->resource = $driver;
return $this;
}
throw new Exception\InvalidArgumentException(
'$driver must be a Sqlsrv PDO Zend\Db\Adapter\Driver or Sqlsrv PDO instance'
);
}
/**
* {@inheritDoc}
*/
public function getName()
{
return 'SQLServer';
}
/**
* {@inheritDoc}
*/
public function getQuoteIdentifierSymbol()
{
return $this->quoteIdentifier;
}
/**
* {@inheritDoc}
*/
public function quoteIdentifierChain($identifierChain)
{
return '[' . implode('].[', (array) $identifierChain) . ']';
}
/**
* {@inheritDoc}
*/
public function quoteValue($value)
{
if ($this->resource instanceof DriverInterface) {
$this->resource = $this->resource->getConnection()->getResource();
}
if ($this->resource instanceof \PDO) {
return $this->resource->quote($value);
}
trigger_error(
'Attempting to quote a value in ' . __CLASS__ . ' without extension/driver support '
. 'can introduce security vulnerabilities in a production environment.'
);
return '\'' . str_replace('\'', '\'\'', addcslashes($value, "\000\032")) . '\'';
}
/**
* {@inheritDoc}
*/
public function quoteTrustedValue($value)
{
if ($this->resource instanceof DriverInterface) {
$this->resource = $this->resource->getConnection()->getResource();
}
if ($this->resource instanceof \PDO) {
return $this->resource->quote($value);
}
return '\'' . str_replace('\'', '\'\'', $value) . '\'';
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Platform/Sqlite.php
================================================
setDriver($driver);
}
}
/**
* @param \Zend\Db\Adapter\Driver\Pdo\Pdo|\PDO $driver
* @return self Provides a fluent interface
* @throws \Zend\Db\Adapter\Exception\InvalidArgumentException
*/
public function setDriver($driver)
{
if (($driver instanceof \PDO && $driver->getAttribute(\PDO::ATTR_DRIVER_NAME) == 'sqlite')
|| ($driver instanceof Pdo\Pdo && $driver->getDatabasePlatformName() == 'Sqlite')
) {
$this->resource = $driver;
return $this;
}
throw new Exception\InvalidArgumentException(
'$driver must be a Sqlite PDO Zend\Db\Adapter\Driver, Sqlite PDO instance'
);
}
/**
* {@inheritDoc}
*/
public function getName()
{
return 'SQLite';
}
/**
* {@inheritDoc}
*/
public function quoteValue($value)
{
$resource = $this->resource;
if ($resource instanceof DriverInterface) {
$resource = $resource->getConnection()->getResource();
}
if ($resource instanceof \PDO) {
return $resource->quote($value);
}
return parent::quoteValue($value);
}
/**
* {@inheritDoc}
*/
public function quoteTrustedValue($value)
{
$resource = $this->resource;
if ($resource instanceof DriverInterface) {
$resource = $resource->getConnection()->getResource();
}
if ($resource instanceof \PDO) {
return $resource->quote($value);
}
return parent::quoteTrustedValue($value);
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Profiler/Profiler.php
================================================
'',
'parameters' => null,
'start' => microtime(true),
'end' => null,
'elapse' => null
];
if ($target instanceof StatementContainerInterface) {
$profileInformation['sql'] = $target->getSql();
$profileInformation['parameters'] = clone $target->getParameterContainer();
} elseif (is_string($target)) {
$profileInformation['sql'] = $target;
} else {
throw new Exception\InvalidArgumentException(
__FUNCTION__ . ' takes either a StatementContainer or a string'
);
}
$this->profiles[$this->currentIndex] = $profileInformation;
return $this;
}
/**
* @return self Provides a fluent interface
*/
public function profilerFinish()
{
if (! isset($this->profiles[$this->currentIndex])) {
throw new Exception\RuntimeException(
'A profile must be started before ' . __FUNCTION__ . ' can be called.'
);
}
$current = &$this->profiles[$this->currentIndex];
$current['end'] = microtime(true);
$current['elapse'] = $current['end'] - $current['start'];
$this->currentIndex++;
return $this;
}
/**
* @return array|null
*/
public function getLastProfile()
{
return end($this->profiles);
}
/**
* @return array
*/
public function getProfiles()
{
return $this->profiles;
}
}
================================================
FILE: src/Zend/Db/src/Adapter/Profiler/ProfilerAwareInterface.php
================================================
setSql($sql);
}
$this->parameterContainer = ($parameterContainer) ?: new ParameterContainer;
}
/**
* @param $sql
* @return self Provides a fluent interface
*/
public function setSql($sql)
{
$this->sql = $sql;
return $this;
}
/**
* @return string
*/
public function getSql()
{
return $this->sql;
}
/**
* @param ParameterContainer $parameterContainer
* @return self Provides a fluent interface
*/
public function setParameterContainer(ParameterContainer $parameterContainer)
{
$this->parameterContainer = $parameterContainer;
return $this;
}
/**
* @return null|ParameterContainer
*/
public function getParameterContainer()
{
return $this->parameterContainer;
}
}
================================================
FILE: src/Zend/Db/src/Adapter/StatementContainerInterface.php
================================================
$this->getDependencyConfig(),
];
}
/**
* Retrieve zend-db default dependency configuration.
*
* @return array
*/
public function getDependencyConfig()
{
return [
'abstract_factories' => [
Adapter\AdapterAbstractServiceFactory::class,
],
'factories' => [
Adapter\AdapterInterface::class => Adapter\AdapterServiceFactory::class,
],
'aliases' => [
Adapter\Adapter::class => Adapter\AdapterInterface::class,
],
];
}
}
================================================
FILE: src/Zend/Db/src/Exception/ErrorException.php
================================================
source = Source\Factory::createSourceFromAdapter($adapter);
}
/**
* {@inheritdoc}
*/
public function getTables($schema = null, $includeViews = false)
{
return $this->source->getTables($schema, $includeViews);
}
/**
* {@inheritdoc}
*/
public function getViews($schema = null)
{
return $this->source->getViews($schema);
}
/**
* {@inheritdoc}
*/
public function getTriggers($schema = null)
{
return $this->source->getTriggers($schema);
}
/**
* {@inheritdoc}
*/
public function getConstraints($table, $schema = null)
{
return $this->source->getConstraints($table, $schema);
}
/**
* {@inheritdoc}
*/
public function getColumns($table, $schema = null)
{
return $this->source->getColumns($table, $schema);
}
/**
* {@inheritdoc}
*/
public function getConstraintKeys($constraint, $table, $schema = null)
{
return $this->source->getConstraintKeys($constraint, $table, $schema);
}
/**
* {@inheritdoc}
*/
public function getConstraint($constraintName, $table, $schema = null)
{
return $this->source->getConstraint($constraintName, $table, $schema);
}
/**
* {@inheritdoc}
*/
public function getSchemas()
{
return $this->source->getSchemas();
}
/**
* {@inheritdoc}
*/
public function getTableNames($schema = null, $includeViews = false)
{
return $this->source->getTableNames($schema, $includeViews);
}
/**
* {@inheritdoc}
*/
public function getTable($tableName, $schema = null)
{
return $this->source->getTable($tableName, $schema);
}
/**
* {@inheritdoc}
*/
public function getViewNames($schema = null)
{
return $this->source->getViewNames($schema);
}
/**
* {@inheritdoc}
*/
public function getView($viewName, $schema = null)
{
return $this->source->getView($viewName, $schema);
}
/**
* {@inheritdoc}
*/
public function getTriggerNames($schema = null)
{
return $this->source->getTriggerNames($schema);
}
/**
* {@inheritdoc}
*/
public function getTrigger($triggerName, $schema = null)
{
return $this->source->getTrigger($triggerName, $schema);
}
/**
* {@inheritdoc}
*/
public function getColumnNames($table, $schema = null)
{
return $this->source->getColumnNames($table, $schema);
}
/**
* {@inheritdoc}
*/
public function getColumn($columnName, $table, $schema = null)
{
return $this->source->getColumn($columnName, $table, $schema);
}
}
================================================
FILE: src/Zend/Db/src/Metadata/MetadataInterface.php
================================================
setName($name);
}
}
/**
* Set columns
*
* @param array $columns
*/
public function setColumns(array $columns)
{
$this->columns = $columns;
}
/**
* Get columns
*
* @return array
*/
public function getColumns()
{
return $this->columns;
}
/**
* Set constraints
*
* @param array $constraints
*/
public function setConstraints($constraints)
{
$this->constraints = $constraints;
}
/**
* Get constraints
*
* @return array
*/
public function getConstraints()
{
return $this->constraints;
}
/**
* Set name
*
* @param string $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
}
================================================
FILE: src/Zend/Db/src/Metadata/Object/ColumnObject.php
================================================
setName($name);
$this->setTableName($tableName);
$this->setSchemaName($schemaName);
}
/**
* Set name
*
* @param string $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Get table name
*
* @return string
*/
public function getTableName()
{
return $this->tableName;
}
/**
* Set table name
*
* @param string $tableName
* @return self Provides a fluent interface
*/
public function setTableName($tableName)
{
$this->tableName = $tableName;
return $this;
}
/**
* Set schema name
*
* @param string $schemaName
*/
public function setSchemaName($schemaName)
{
$this->schemaName = $schemaName;
}
/**
* Get schema name
*
* @return string
*/
public function getSchemaName()
{
return $this->schemaName;
}
/**
* @return int $ordinalPosition
*/
public function getOrdinalPosition()
{
return $this->ordinalPosition;
}
/**
* @param int $ordinalPosition to set
* @return self Provides a fluent interface
*/
public function setOrdinalPosition($ordinalPosition)
{
$this->ordinalPosition = $ordinalPosition;
return $this;
}
/**
* @return null|string the $columnDefault
*/
public function getColumnDefault()
{
return $this->columnDefault;
}
/**
* @param mixed $columnDefault to set
* @return self Provides a fluent interface
*/
public function setColumnDefault($columnDefault)
{
$this->columnDefault = $columnDefault;
return $this;
}
/**
* @return bool $isNullable
*/
public function getIsNullable()
{
return $this->isNullable;
}
/**
* @param bool $isNullable to set
* @return self Provides a fluent interface
*/
public function setIsNullable($isNullable)
{
$this->isNullable = $isNullable;
return $this;
}
/**
* @return bool $isNullable
*/
public function isNullable()
{
return $this->isNullable;
}
/**
* @return null|string the $dataType
*/
public function getDataType()
{
return $this->dataType;
}
/**
* @param string $dataType the $dataType to set
* @return self Provides a fluent interface
*/
public function setDataType($dataType)
{
$this->dataType = $dataType;
return $this;
}
/**
* @return int|null the $characterMaximumLength
*/
public function getCharacterMaximumLength()
{
return $this->characterMaximumLength;
}
/**
* @param int $characterMaximumLength the $characterMaximumLength to set
* @return self Provides a fluent interface
*/
public function setCharacterMaximumLength($characterMaximumLength)
{
$this->characterMaximumLength = $characterMaximumLength;
return $this;
}
/**
* @return int|null the $characterOctetLength
*/
public function getCharacterOctetLength()
{
return $this->characterOctetLength;
}
/**
* @param int $characterOctetLength the $characterOctetLength to set
* @return self Provides a fluent interface
*/
public function setCharacterOctetLength($characterOctetLength)
{
$this->characterOctetLength = $characterOctetLength;
return $this;
}
/**
* @return int the $numericPrecision
*/
public function getNumericPrecision()
{
return $this->numericPrecision;
}
/**
* @param int $numericPrecision the $numericPrevision to set
* @return self Provides a fluent interface
*/
public function setNumericPrecision($numericPrecision)
{
$this->numericPrecision = $numericPrecision;
return $this;
}
/**
* @return int the $numericScale
*/
public function getNumericScale()
{
return $this->numericScale;
}
/**
* @param int $numericScale the $numericScale to set
* @return self Provides a fluent interface
*/
public function setNumericScale($numericScale)
{
$this->numericScale = $numericScale;
return $this;
}
/**
* @return bool
*/
public function getNumericUnsigned()
{
return $this->numericUnsigned;
}
/**
* @param bool $numericUnsigned
* @return self Provides a fluent interface
*/
public function setNumericUnsigned($numericUnsigned)
{
$this->numericUnsigned = $numericUnsigned;
return $this;
}
/**
* @return bool
*/
public function isNumericUnsigned()
{
return $this->numericUnsigned;
}
/**
* @return array the $errata
*/
public function getErratas()
{
return $this->errata;
}
/**
* @param array $erratas
* @return self Provides a fluent interface
*/
public function setErratas(array $erratas)
{
foreach ($erratas as $name => $value) {
$this->setErrata($name, $value);
}
return $this;
}
/**
* @param string $errataName
* @return mixed
*/
public function getErrata($errataName)
{
if (array_key_exists($errataName, $this->errata)) {
return $this->errata[$errataName];
}
return;
}
/**
* @param string $errataName
* @param mixed $errataValue
* @return self Provides a fluent interface
*/
public function setErrata($errataName, $errataValue)
{
$this->errata[$errataName] = $errataValue;
return $this;
}
}
================================================
FILE: src/Zend/Db/src/Metadata/Object/ConstraintKeyObject.php
================================================
setColumnName($column);
}
/**
* Get column name
*
* @return string
*/
public function getColumnName()
{
return $this->columnName;
}
/**
* Set column name
*
* @param string $columnName
* @return self Provides a fluent interface
*/
public function setColumnName($columnName)
{
$this->columnName = $columnName;
return $this;
}
/**
* Get ordinal position
*
* @return int
*/
public function getOrdinalPosition()
{
return $this->ordinalPosition;
}
/**
* Set ordinal position
*
* @param int $ordinalPosition
* @return self Provides a fluent interface
*/
public function setOrdinalPosition($ordinalPosition)
{
$this->ordinalPosition = $ordinalPosition;
return $this;
}
/**
* Get position in unique constraint
*
* @return bool
*/
public function getPositionInUniqueConstraint()
{
return $this->positionInUniqueConstraint;
}
/**
* Set position in unique constraint
*
* @param bool $positionInUniqueConstraint
* @return self Provides a fluent interface
*/
public function setPositionInUniqueConstraint($positionInUniqueConstraint)
{
$this->positionInUniqueConstraint = $positionInUniqueConstraint;
return $this;
}
/**
* Get referencred table schema
*
* @return string
*/
public function getReferencedTableSchema()
{
return $this->referencedTableSchema;
}
/**
* Set referenced table schema
*
* @param string $referencedTableSchema
* @return self Provides a fluent interface
*/
public function setReferencedTableSchema($referencedTableSchema)
{
$this->referencedTableSchema = $referencedTableSchema;
return $this;
}
/**
* Get referenced table name
*
* @return string
*/
public function getReferencedTableName()
{
return $this->referencedTableName;
}
/**
* Set Referenced table name
*
* @param string $referencedTableName
* @return self Provides a fluent interface
*/
public function setReferencedTableName($referencedTableName)
{
$this->referencedTableName = $referencedTableName;
return $this;
}
/**
* Get referenced column name
*
* @return string
*/
public function getReferencedColumnName()
{
return $this->referencedColumnName;
}
/**
* Set referenced column name
*
* @param string $referencedColumnName
* @return self Provides a fluent interface
*/
public function setReferencedColumnName($referencedColumnName)
{
$this->referencedColumnName = $referencedColumnName;
return $this;
}
/**
* set foreign key update rule
*
* @param string $foreignKeyUpdateRule
*/
public function setForeignKeyUpdateRule($foreignKeyUpdateRule)
{
$this->foreignKeyUpdateRule = $foreignKeyUpdateRule;
}
/**
* Get foreign key update rule
*
* @return string
*/
public function getForeignKeyUpdateRule()
{
return $this->foreignKeyUpdateRule;
}
/**
* Set foreign key delete rule
*
* @param string $foreignKeyDeleteRule
*/
public function setForeignKeyDeleteRule($foreignKeyDeleteRule)
{
$this->foreignKeyDeleteRule = $foreignKeyDeleteRule;
}
/**
* get foreign key delete rule
*
* @return string
*/
public function getForeignKeyDeleteRule()
{
return $this->foreignKeyDeleteRule;
}
}
================================================
FILE: src/Zend/Db/src/Metadata/Object/ConstraintObject.php
================================================
setName($name);
$this->setTableName($tableName);
$this->setSchemaName($schemaName);
}
/**
* Set name
*
* @param string $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set schema name
*
* @param string $schemaName
*/
public function setSchemaName($schemaName)
{
$this->schemaName = $schemaName;
}
/**
* Get schema name
*
* @return string
*/
public function getSchemaName()
{
return $this->schemaName;
}
/**
* Get table name
*
* @return string
*/
public function getTableName()
{
return $this->tableName;
}
/**
* Set table name
*
* @param string $tableName
* @return self Provides a fluent interface
*/
public function setTableName($tableName)
{
$this->tableName = $tableName;
return $this;
}
/**
* Set type
*
* @param string $type
*/
public function setType($type)
{
$this->type = $type;
}
/**
* Get type
*
* @return string
*/
public function getType()
{
return $this->type;
}
public function hasColumns()
{
return (! empty($this->columns));
}
/**
* Get Columns.
*
* @return string[]
*/
public function getColumns()
{
return $this->columns;
}
/**
* Set Columns.
*
* @param string[] $columns
* @return self Provides a fluent interface
*/
public function setColumns(array $columns)
{
$this->columns = $columns;
return $this;
}
/**
* Get Referenced Table Schema.
*
* @return string
*/
public function getReferencedTableSchema()
{
return $this->referencedTableSchema;
}
/**
* Set Referenced Table Schema.
*
* @param string $referencedTableSchema
* @return self Provides a fluent interface
*/
public function setReferencedTableSchema($referencedTableSchema)
{
$this->referencedTableSchema = $referencedTableSchema;
return $this;
}
/**
* Get Referenced Table Name.
*
* @return string
*/
public function getReferencedTableName()
{
return $this->referencedTableName;
}
/**
* Set Referenced Table Name.
*
* @param string $referencedTableName
* @return self Provides a fluent interface
*/
public function setReferencedTableName($referencedTableName)
{
$this->referencedTableName = $referencedTableName;
return $this;
}
/**
* Get Referenced Columns.
*
* @return string[]
*/
public function getReferencedColumns()
{
return $this->referencedColumns;
}
/**
* Set Referenced Columns.
*
* @param string[] $referencedColumns
* @return self Provides a fluent interface
*/
public function setReferencedColumns(array $referencedColumns)
{
$this->referencedColumns = $referencedColumns;
return $this;
}
/**
* Get Match Option.
*
* @return string
*/
public function getMatchOption()
{
return $this->matchOption;
}
/**
* Set Match Option.
*
* @param string $matchOption
* @return self Provides a fluent interface
*/
public function setMatchOption($matchOption)
{
$this->matchOption = $matchOption;
return $this;
}
/**
* Get Update Rule.
*
* @return string
*/
public function getUpdateRule()
{
return $this->updateRule;
}
/**
* Set Update Rule.
*
* @param string $updateRule
* @return self Provides a fluent interface
*/
public function setUpdateRule($updateRule)
{
$this->updateRule = $updateRule;
return $this;
}
/**
* Get Delete Rule.
*
* @return string
*/
public function getDeleteRule()
{
return $this->deleteRule;
}
/**
* Set Delete Rule.
*
* @param string $deleteRule
* @return self Provides a fluent interface
*/
public function setDeleteRule($deleteRule)
{
$this->deleteRule = $deleteRule;
return $this;
}
/**
* Get Check Clause.
*
* @return string
*/
public function getCheckClause()
{
return $this->checkClause;
}
/**
* Set Check Clause.
*
* @param string $checkClause
* @return self Provides a fluent interface
*/
public function setCheckClause($checkClause)
{
$this->checkClause = $checkClause;
return $this;
}
/**
* Is primary key
*
* @return bool
*/
public function isPrimaryKey()
{
return ('PRIMARY KEY' == $this->type);
}
/**
* Is unique key
*
* @return bool
*/
public function isUnique()
{
return ('UNIQUE' == $this->type);
}
/**
* Is foreign key
*
* @return bool
*/
public function isForeignKey()
{
return ('FOREIGN KEY' == $this->type);
}
/**
* Is foreign key
*
* @return bool
*/
public function isCheck()
{
return ('CHECK' == $this->type);
}
}
================================================
FILE: src/Zend/Db/src/Metadata/Object/TableObject.php
================================================
name;
}
/**
* Set Name.
*
* @param string $name
* @return self Provides a fluent interface
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get Event Manipulation.
*
* @return string
*/
public function getEventManipulation()
{
return $this->eventManipulation;
}
/**
* Set Event Manipulation.
*
* @param string $eventManipulation
* @return self Provides a fluent interface
*/
public function setEventManipulation($eventManipulation)
{
$this->eventManipulation = $eventManipulation;
return $this;
}
/**
* Get Event Object Catalog.
*
* @return string
*/
public function getEventObjectCatalog()
{
return $this->eventObjectCatalog;
}
/**
* Set Event Object Catalog.
*
* @param string $eventObjectCatalog
* @return self Provides a fluent interface
*/
public function setEventObjectCatalog($eventObjectCatalog)
{
$this->eventObjectCatalog = $eventObjectCatalog;
return $this;
}
/**
* Get Event Object Schema.
*
* @return string
*/
public function getEventObjectSchema()
{
return $this->eventObjectSchema;
}
/**
* Set Event Object Schema.
*
* @param string $eventObjectSchema
* @return self Provides a fluent interface
*/
public function setEventObjectSchema($eventObjectSchema)
{
$this->eventObjectSchema = $eventObjectSchema;
return $this;
}
/**
* Get Event Object Table.
*
* @return string
*/
public function getEventObjectTable()
{
return $this->eventObjectTable;
}
/**
* Set Event Object Table.
*
* @param string $eventObjectTable
* @return self Provides a fluent interface
*/
public function setEventObjectTable($eventObjectTable)
{
$this->eventObjectTable = $eventObjectTable;
return $this;
}
/**
* Get Action Order.
*
* @return string
*/
public function getActionOrder()
{
return $this->actionOrder;
}
/**
* Set Action Order.
*
* @param string $actionOrder
* @return self Provides a fluent interface
*/
public function setActionOrder($actionOrder)
{
$this->actionOrder = $actionOrder;
return $this;
}
/**
* Get Action Condition.
*
* @return string
*/
public function getActionCondition()
{
return $this->actionCondition;
}
/**
* Set Action Condition.
*
* @param string $actionCondition
* @return self Provides a fluent interface
*/
public function setActionCondition($actionCondition)
{
$this->actionCondition = $actionCondition;
return $this;
}
/**
* Get Action Statement.
*
* @return string
*/
public function getActionStatement()
{
return $this->actionStatement;
}
/**
* Set Action Statement.
*
* @param string $actionStatement
* @return self Provides a fluent interface
*/
public function setActionStatement($actionStatement)
{
$this->actionStatement = $actionStatement;
return $this;
}
/**
* Get Action Orientation.
*
* @return string
*/
public function getActionOrientation()
{
return $this->actionOrientation;
}
/**
* Set Action Orientation.
*
* @param string $actionOrientation
* @return self Provides a fluent interface
*/
public function setActionOrientation($actionOrientation)
{
$this->actionOrientation = $actionOrientation;
return $this;
}
/**
* Get Action Timing.
*
* @return string
*/
public function getActionTiming()
{
return $this->actionTiming;
}
/**
* Set Action Timing.
*
* @param string $actionTiming
* @return self Provides a fluent interface
*/
public function setActionTiming($actionTiming)
{
$this->actionTiming = $actionTiming;
return $this;
}
/**
* Get Action Reference Old Table.
*
* @return string
*/
public function getActionReferenceOldTable()
{
return $this->actionReferenceOldTable;
}
/**
* Set Action Reference Old Table.
*
* @param string $actionReferenceOldTable
* @return self Provides a fluent interface
*/
public function setActionReferenceOldTable($actionReferenceOldTable)
{
$this->actionReferenceOldTable = $actionReferenceOldTable;
return $this;
}
/**
* Get Action Reference New Table.
*
* @return string
*/
public function getActionReferenceNewTable()
{
return $this->actionReferenceNewTable;
}
/**
* Set Action Reference New Table.
*
* @param string $actionReferenceNewTable
* @return self Provides a fluent interface
*/
public function setActionReferenceNewTable($actionReferenceNewTable)
{
$this->actionReferenceNewTable = $actionReferenceNewTable;
return $this;
}
/**
* Get Action Reference Old Row.
*
* @return string
*/
public function getActionReferenceOldRow()
{
return $this->actionReferenceOldRow;
}
/**
* Set Action Reference Old Row.
*
* @param string $actionReferenceOldRow
* @return self Provides a fluent interface
*/
public function setActionReferenceOldRow($actionReferenceOldRow)
{
$this->actionReferenceOldRow = $actionReferenceOldRow;
return $this;
}
/**
* Get Action Reference New Row.
*
* @return string
*/
public function getActionReferenceNewRow()
{
return $this->actionReferenceNewRow;
}
/**
* Set Action Reference New Row.
*
* @param string $actionReferenceNewRow
* @return self Provides a fluent interface
*/
public function setActionReferenceNewRow($actionReferenceNewRow)
{
$this->actionReferenceNewRow = $actionReferenceNewRow;
return $this;
}
/**
* Get Created.
*
* @return \DateTime
*/
public function getCreated()
{
return $this->created;
}
/**
* Set Created.
*
* @param \DateTime $created
* @return self Provides a fluent interface
*/
public function setCreated($created)
{
$this->created = $created;
return $this;
}
}
================================================
FILE: src/Zend/Db/src/Metadata/Object/ViewObject.php
================================================
viewDefinition;
}
/**
* @param string $viewDefinition to set
* @return self Provides a fluent interface
*/
public function setViewDefinition($viewDefinition)
{
$this->viewDefinition = $viewDefinition;
return $this;
}
/**
* @return string $checkOption
*/
public function getCheckOption()
{
return $this->checkOption;
}
/**
* @param string $checkOption to set
* @return self Provides a fluent interface
*/
public function setCheckOption($checkOption)
{
$this->checkOption = $checkOption;
return $this;
}
/**
* @return bool $isUpdatable
*/
public function getIsUpdatable()
{
return $this->isUpdatable;
}
/**
* @param bool $isUpdatable to set
* @return self Provides a fluent interface
*/
public function setIsUpdatable($isUpdatable)
{
$this->isUpdatable = $isUpdatable;
return $this;
}
public function isUpdatable()
{
return $this->isUpdatable;
}
}
================================================
FILE: src/Zend/Db/src/Metadata/Source/AbstractSource.php
================================================
adapter = $adapter;
$this->defaultSchema = ($adapter->getCurrentSchema()) ?: self::DEFAULT_SCHEMA;
}
/**
* Get schemas
*
*/
public function getSchemas()
{
$this->loadSchemaData();
return $this->data['schemas'];
}
/**
* {@inheritdoc}
*/
public function getTableNames($schema = null, $includeViews = false)
{
if ($schema === null) {
$schema = $this->defaultSchema;
}
$this->loadTableNameData($schema);
if ($includeViews) {
return array_keys($this->data['table_names'][$schema]);
}
$tableNames = [];
foreach ($this->data['table_names'][$schema] as $tableName => $data) {
if ('BASE TABLE' == $data['table_type']) {
$tableNames[] = $tableName;
}
}
return $tableNames;
}
/**
* {@inheritdoc}
*/
public function getTables($schema = null, $includeViews = false)
{
if ($schema === null) {
$schema = $this->defaultSchema;
}
$tables = [];
foreach ($this->getTableNames($schema, $includeViews) as $tableName) {
$tables[] = $this->getTable($tableName, $schema);
}
return $tables;
}
/**
* {@inheritdoc}
*/
public function getTable($tableName, $schema = null)
{
if ($schema === null) {
$schema = $this->defaultSchema;
}
$this->loadTableNameData($schema);
if (! isset($this->data['table_names'][$schema][$tableName])) {
throw new \Exception('Table "' . $tableName . '" does not exist');
}
$data = $this->data['table_names'][$schema][$tableName];
switch ($data['table_type']) {
case 'BASE TABLE':
$table = new TableObject($tableName);
break;
case 'VIEW':
$table = new ViewObject($tableName);
$table->setViewDefinition($data['view_definition']);
$table->setCheckOption($data['check_option']);
$table->setIsUpdatable($data['is_updatable']);
break;
default:
throw new \Exception(
'Table "' . $tableName . '" is of an unsupported type "' . $data['table_type'] . '"'
);
}
$table->setColumns($this->getColumns($tableName, $schema));
$table->setConstraints($this->getConstraints($tableName, $schema));
return $table;
}
/**
* {@inheritdoc}
*/
public function getViewNames($schema = null)
{
if ($schema === null) {
$schema = $this->defaultSchema;
}
$this->loadTableNameData($schema);
$viewNames = [];
foreach ($this->data['table_names'][$schema] as $tableName => $data) {
if ('VIEW' == $data['table_type']) {
$viewNames[] = $tableName;
}
}
return $viewNames;
}
/**
* {@inheritdoc}
*/
public function getViews($schema = null)
{
if ($schema === null) {
$schema = $this->defaultSchema;
}
$views = [];
foreach ($this->getViewNames($schema) as $tableName) {
$views[] = $this->getTable($tableName, $schema);
}
return $views;
}
/**
* {@inheritdoc}
*/
public function getView($viewName, $schema = null)
{
if ($schema === null) {
$schema = $this->defaultSchema;
}
$this->loadTableNameData($schema);
$tableNames = $this->data['table_names'][$schema];
if (isset($tableNames[$viewName]) && 'VIEW' == $tableNames[$viewName]['table_type']) {
return $this->getTable($viewName, $schema);
}
throw new \Exception('View "' . $viewName . '" does not exist');
}
/**
* {@inheritdoc}
*/
public function getColumnNames($table, $schema = null)
{
if ($schema === null) {
$schema = $this->defaultSchema;
}
$this->loadColumnData($table, $schema);
if (! isset($this->data['columns'][$schema][$table])) {
throw new \Exception('"' . $table . '" does not exist');
}
return array_keys($this->data['columns'][$schema][$table]);
}
/**
* {@inheritdoc}
*/
public function getColumns($table, $schema = null)
{
if ($schema === null) {
$schema = $this->defaultSchema;
}
$this->loadColumnData($table, $schema);
$columns = [];
foreach ($this->getColumnNames($table, $schema) as $columnName) {
$columns[] = $this->getColumn($columnName, $table, $schema);
}
return $columns;
}
/**
* {@inheritdoc}
*/
public function getColumn($columnName, $table, $schema = null)
{
if ($schema === null) {
$schema = $this->defaultSchema;
}
$this->loadColumnData($table, $schema);
if (! isset($this->data['columns'][$schema][$table][$columnName])) {
throw new \Exception('A column by that name was not found.');
}
$info = $this->data['columns'][$schema][$table][$columnName];
$column = new ColumnObject($columnName, $table, $schema);
$props = [
'ordinal_position', 'column_default', 'is_nullable',
'data_type', 'character_maximum_length', 'character_octet_length',
'numeric_precision', 'numeric_scale', 'numeric_unsigned',
'erratas'
];
foreach ($props as $prop) {
if (isset($info[$prop])) {
$column->{'set' . str_replace('_', '', $prop)}($info[$prop]);
}
}
$column->setOrdinalPosition($info['ordinal_position']);
$column->setColumnDefault($info['column_default']);
$column->setIsNullable($info['is_nullable']);
$column->setDataType($info['data_type']);
$column->setCharacterMaximumLength($info['character_maximum_length']);
$column->setCharacterOctetLength($info['character_octet_length']);
$column->setNumericPrecision($info['numeric_precision']);
$column->setNumericScale($info['numeric_scale']);
$column->setNumericUnsigned($info['numeric_unsigned']);
$column->setErratas($info['erratas']);
return $column;
}
/**
* {@inheritdoc}
*/
public function getConstraints($table, $schema = null)
{
if ($schema === null) {
$schema = $this->defaultSchema;
}
$this->loadConstraintData($table, $schema);
$constraints = [];
foreach (array_keys($this->data['constraints'][$schema][$table]) as $constraintName) {
$constraints[] = $this->getConstraint($constraintName, $table, $schema);
}
return $constraints;
}
/**
* {@inheritdoc}
*/
public function getConstraint($constraintName, $table, $schema = null)
{
if ($schema === null) {
$schema = $this->defaultSchema;
}
$this->loadConstraintData($table, $schema);
if (! isset($this->data['constraints'][$schema][$table][$constraintName])) {
throw new \Exception('Cannot find a constraint by that name in this table');
}
$info = $this->data['constraints'][$schema][$table][$constraintName];
$constraint = new ConstraintObject($constraintName, $table, $schema);
foreach ([
'constraint_type' => 'setType',
'match_option' => 'setMatchOption',
'update_rule' => 'setUpdateRule',
'delete_rule' => 'setDeleteRule',
'columns' => 'setColumns',
'referenced_table_schema' => 'setReferencedTableSchema',
'referenced_table_name' => 'setReferencedTableName',
'referenced_columns' => 'setReferencedColumns',
'check_clause' => 'setCheckClause',
] as $key => $setMethod) {
if (isset($info[$key])) {
$constraint->{$setMethod}($info[$key]);
}
}
return $constraint;
}
/**
* {@inheritdoc}
*/
public function getConstraintKeys($constraint, $table, $schema = null)
{
if ($schema === null) {
$schema = $this->defaultSchema;
}
$this->loadConstraintReferences($table, $schema);
// organize references first
$references = [];
foreach ($this->data['constraint_references'][$schema] as $refKeyInfo) {
if ($refKeyInfo['constraint_name'] == $constraint) {
$references[$refKeyInfo['constraint_name']] = $refKeyInfo;
}
}
$this->loadConstraintDataKeys($schema);
$keys = [];
foreach ($this->data['constraint_keys'][$schema] as $constraintKeyInfo) {
if ($constraintKeyInfo['table_name'] == $table && $constraintKeyInfo['constraint_name'] === $constraint) {
$keys[] = $key = new ConstraintKeyObject($constraintKeyInfo['column_name']);
$key->setOrdinalPosition($constraintKeyInfo['ordinal_position']);
if (isset($references[$constraint])) {
//$key->setReferencedTableSchema($constraintKeyInfo['referenced_table_schema']);
$key->setForeignKeyUpdateRule($references[$constraint]['update_rule']);
$key->setForeignKeyDeleteRule($references[$constraint]['delete_rule']);
//$key->setReferencedTableSchema($references[$constraint]['referenced_table_schema']);
$key->setReferencedTableName($references[$constraint]['referenced_table_name']);
$key->setReferencedColumnName($references[$constraint]['referenced_column_name']);
}
}
}
return $keys;
}
/**
* {@inheritdoc}
*/
public function getTriggerNames($schema = null)
{
if ($schema === null) {
$schema = $this->defaultSchema;
}
$this->loadTriggerData($schema);
return array_keys($this->data['triggers'][$schema]);
}
/**
* {@inheritdoc}
*/
public function getTriggers($schema = null)
{
if ($schema === null) {
$schema = $this->defaultSchema;
}
$triggers = [];
foreach ($this->getTriggerNames($schema) as $triggerName) {
$triggers[] = $this->getTrigger($triggerName, $schema);
}
return $triggers;
}
/**
* {@inheritdoc}
*/
public function getTrigger($triggerName, $schema = null)
{
if ($schema === null) {
$schema = $this->defaultSchema;
}
$this->loadTriggerData($schema);
if (! isset($this->data['triggers'][$schema][$triggerName])) {
throw new \Exception('Trigger "' . $triggerName . '" does not exist');
}
$info = $this->data['triggers'][$schema][$triggerName];
$trigger = new TriggerObject();
$trigger->setName($triggerName);
$trigger->setEventManipulation($info['event_manipulation']);
$trigger->setEventObjectCatalog($info['event_object_catalog']);
$trigger->setEventObjectSchema($info['event_object_schema']);
$trigger->setEventObjectTable($info['event_object_table']);
$trigger->setActionOrder($info['action_order']);
$trigger->setActionCondition($info['action_condition']);
$trigger->setActionStatement($info['action_statement']);
$trigger->setActionOrientation($info['action_orientation']);
$trigger->setActionTiming($info['action_timing']);
$trigger->setActionReferenceOldTable($info['action_reference_old_table']);
$trigger->setActionReferenceNewTable($info['action_reference_new_table']);
$trigger->setActionReferenceOldRow($info['action_reference_old_row']);
$trigger->setActionReferenceNewRow($info['action_reference_new_row']);
$trigger->setCreated($info['created']);
return $trigger;
}
/**
* Prepare data hierarchy
*
* @param string $type
* @param string $key ...
*/
protected function prepareDataHierarchy($type)
{
$data = &$this->data;
foreach (func_get_args() as $key) {
if (! isset($data[$key])) {
$data[$key] = [];
}
$data = &$data[$key];
}
}
/**
* Load schema data
*/
protected function loadSchemaData()
{
}
/**
* Load table name data
*
* @param string $schema
*/
protected function loadTableNameData($schema)
{
if (isset($this->data['table_names'][$schema])) {
return;
}
$this->prepareDataHierarchy('table_names', $schema);
}
/**
* Load column data
*
* @param string $table
* @param string $schema
*/
protected function loadColumnData($table, $schema)
{
if (isset($this->data['columns'][$schema][$table])) {
return;
}
$this->prepareDataHierarchy('columns', $schema, $table);
}
/**
* Load constraint data
*
* @param string $table
* @param string $schema
*/
protected function loadConstraintData($table, $schema)
{
if (isset($this->data['constraints'][$schema])) {
return;
}
$this->prepareDataHierarchy('constraints', $schema);
}
/**
* Load constraint data keys
*
* @param string $schema
*/
protected function loadConstraintDataKeys($schema)
{
if (isset($this->data['constraint_keys'][$schema])) {
return;
}
$this->prepareDataHierarchy('constraint_keys', $schema);
}
/**
* Load constraint references
*
* @param string $table
* @param string $schema
*/
protected function loadConstraintReferences($table, $schema)
{
if (isset($this->data['constraint_references'][$schema])) {
return;
}
$this->prepareDataHierarchy('constraint_references', $schema);
}
/**
* Load trigger data
*
* @param string $schema
*/
protected function loadTriggerData($schema)
{
if (isset($this->data['triggers'][$schema])) {
return;
}
$this->prepareDataHierarchy('triggers', $schema);
}
}
================================================
FILE: src/Zend/Db/src/Metadata/Source/Factory.php
================================================
getPlatform()->getName();
switch ($platformName) {
case 'MySQL':
return new MysqlMetadata($adapter);
case 'SQLServer':
return new SqlServerMetadata($adapter);
case 'SQLite':
return new SqliteMetadata($adapter);
case 'PostgreSQL':
return new PostgresqlMetadata($adapter);
case 'Oracle':
return new OracleMetadata($adapter);
default:
throw new InvalidArgumentException("Unknown adapter platform '{$platformName}'");
}
}
}
================================================
FILE: src/Zend/Db/src/Metadata/Source/MysqlMetadata.php
================================================
data['schemas'])) {
return;
}
$this->prepareDataHierarchy('schemas');
$p = $this->adapter->getPlatform();
$sql = 'SELECT ' . $p->quoteIdentifier('SCHEMA_NAME')
. ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'SCHEMATA'])
. ' WHERE ' . $p->quoteIdentifier('SCHEMA_NAME')
. ' != \'INFORMATION_SCHEMA\'';
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$schemas = [];
foreach ($results->toArray() as $row) {
$schemas[] = $row['SCHEMA_NAME'];
}
$this->data['schemas'] = $schemas;
}
protected function loadTableNameData($schema)
{
if (isset($this->data['table_names'][$schema])) {
return;
}
$this->prepareDataHierarchy('table_names', $schema);
$p = $this->adapter->getPlatform();
$isColumns = [
['T', 'TABLE_NAME'],
['T', 'TABLE_TYPE'],
['V', 'VIEW_DEFINITION'],
['V', 'CHECK_OPTION'],
['V', 'IS_UPDATABLE'],
];
array_walk($isColumns, function (&$c) use ($p) {
$c = $p->quoteIdentifierChain($c);
});
$sql = 'SELECT ' . implode(', ', $isColumns)
. ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLES']) . 'T'
. ' LEFT JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'VIEWS']) . ' V'
. ' ON ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' = ' . $p->quoteIdentifierChain(['V', 'TABLE_SCHEMA'])
. ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME'])
. ' = ' . $p->quoteIdentifierChain(['V', 'TABLE_NAME'])
. ' WHERE ' . $p->quoteIdentifierChain(['T', 'TABLE_TYPE'])
. ' IN (\'BASE TABLE\', \'VIEW\')';
if ($schema != self::DEFAULT_SCHEMA) {
$sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' = ' . $p->quoteTrustedValue($schema);
} else {
$sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' != \'INFORMATION_SCHEMA\'';
}
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$tables = [];
foreach ($results->toArray() as $row) {
$tables[$row['TABLE_NAME']] = [
'table_type' => $row['TABLE_TYPE'],
'view_definition' => $row['VIEW_DEFINITION'],
'check_option' => $row['CHECK_OPTION'],
'is_updatable' => ('YES' == $row['IS_UPDATABLE']),
];
}
$this->data['table_names'][$schema] = $tables;
}
protected function loadColumnData($table, $schema)
{
if (isset($this->data['columns'][$schema][$table])) {
return;
}
$this->prepareDataHierarchy('columns', $schema, $table);
$p = $this->adapter->getPlatform();
$isColumns = [
['C', 'ORDINAL_POSITION'],
['C', 'COLUMN_DEFAULT'],
['C', 'IS_NULLABLE'],
['C', 'DATA_TYPE'],
['C', 'CHARACTER_MAXIMUM_LENGTH'],
['C', 'CHARACTER_OCTET_LENGTH'],
['C', 'NUMERIC_PRECISION'],
['C', 'NUMERIC_SCALE'],
['C', 'COLUMN_NAME'],
['C', 'COLUMN_TYPE'],
];
array_walk($isColumns, function (&$c) use ($p) {
$c = $p->quoteIdentifierChain($c);
});
$sql = 'SELECT ' . implode(', ', $isColumns)
. ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLES']) . 'T'
. ' INNER JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'COLUMNS']) . 'C'
. ' ON ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' = ' . $p->quoteIdentifierChain(['C', 'TABLE_SCHEMA'])
. ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME'])
. ' = ' . $p->quoteIdentifierChain(['C', 'TABLE_NAME'])
. ' WHERE ' . $p->quoteIdentifierChain(['T', 'TABLE_TYPE'])
. ' IN (\'BASE TABLE\', \'VIEW\')'
. ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME'])
. ' = ' . $p->quoteTrustedValue($table);
if ($schema != self::DEFAULT_SCHEMA) {
$sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' = ' . $p->quoteTrustedValue($schema);
} else {
$sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' != \'INFORMATION_SCHEMA\'';
}
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$columns = [];
foreach ($results->toArray() as $row) {
$erratas = [];
$matches = [];
if (preg_match('/^(?:enum|set)\((.+)\)$/i', $row['COLUMN_TYPE'], $matches)) {
$permittedValues = $matches[1];
if (preg_match_all(
"/\\s*'((?:[^']++|'')*+)'\\s*(?:,|\$)/",
$permittedValues,
$matches,
PREG_PATTERN_ORDER
)
) {
$permittedValues = str_replace("''", "'", $matches[1]);
} else {
$permittedValues = [$permittedValues];
}
$erratas['permitted_values'] = $permittedValues;
}
$columns[$row['COLUMN_NAME']] = [
'ordinal_position' => $row['ORDINAL_POSITION'],
'column_default' => $row['COLUMN_DEFAULT'],
'is_nullable' => ('YES' == $row['IS_NULLABLE']),
'data_type' => $row['DATA_TYPE'],
'character_maximum_length' => $row['CHARACTER_MAXIMUM_LENGTH'],
'character_octet_length' => $row['CHARACTER_OCTET_LENGTH'],
'numeric_precision' => $row['NUMERIC_PRECISION'],
'numeric_scale' => $row['NUMERIC_SCALE'],
'numeric_unsigned' => (str_contains($row['COLUMN_TYPE'], 'unsigned')),
'erratas' => $erratas,
];
}
$this->data['columns'][$schema][$table] = $columns;
}
protected function loadConstraintData($table, $schema)
{
if (isset($this->data['constraints'][$schema][$table])) {
return;
}
$this->prepareDataHierarchy('constraints', $schema, $table);
$isColumns = [
['T', 'TABLE_NAME'],
['TC', 'CONSTRAINT_NAME'],
['TC', 'CONSTRAINT_TYPE'],
['KCU', 'COLUMN_NAME'],
['RC', 'MATCH_OPTION'],
['RC', 'UPDATE_RULE'],
['RC', 'DELETE_RULE'],
['KCU', 'REFERENCED_TABLE_SCHEMA'],
['KCU', 'REFERENCED_TABLE_NAME'],
['KCU', 'REFERENCED_COLUMN_NAME'],
];
$p = $this->adapter->getPlatform();
array_walk($isColumns, function (&$c) use ($p) {
$c = $p->quoteIdentifierChain($c);
});
$sql = 'SELECT ' . implode(', ', $isColumns)
. ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLES']) . ' T'
. ' INNER JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLE_CONSTRAINTS']) . ' TC'
. ' ON ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' = ' . $p->quoteIdentifierChain(['TC', 'TABLE_SCHEMA'])
. ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME'])
. ' = ' . $p->quoteIdentifierChain(['TC', 'TABLE_NAME'])
. ' LEFT JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'KEY_COLUMN_USAGE']) . ' KCU'
. ' ON ' . $p->quoteIdentifierChain(['TC', 'TABLE_SCHEMA'])
. ' = ' . $p->quoteIdentifierChain(['KCU', 'TABLE_SCHEMA'])
. ' AND ' . $p->quoteIdentifierChain(['TC', 'TABLE_NAME'])
. ' = ' . $p->quoteIdentifierChain(['KCU', 'TABLE_NAME'])
. ' AND ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_NAME'])
. ' = ' . $p->quoteIdentifierChain(['KCU', 'CONSTRAINT_NAME'])
. ' LEFT JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'REFERENTIAL_CONSTRAINTS']) . ' RC'
. ' ON ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_SCHEMA'])
. ' = ' . $p->quoteIdentifierChain(['RC', 'CONSTRAINT_SCHEMA'])
. ' AND ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_NAME'])
. ' = ' . $p->quoteIdentifierChain(['RC', 'CONSTRAINT_NAME'])
. ' WHERE ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME'])
. ' = ' . $p->quoteTrustedValue($table)
. ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_TYPE'])
. ' IN (\'BASE TABLE\', \'VIEW\')';
if ($schema != self::DEFAULT_SCHEMA) {
$sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' = ' . $p->quoteTrustedValue($schema);
} else {
$sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' != \'INFORMATION_SCHEMA\'';
}
$sql .= ' ORDER BY CASE ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_TYPE'])
. " WHEN 'PRIMARY KEY' THEN 1"
. " WHEN 'UNIQUE' THEN 2"
. " WHEN 'FOREIGN KEY' THEN 3"
. " ELSE 4 END"
. ', ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_NAME'])
. ', ' . $p->quoteIdentifierChain(['KCU', 'ORDINAL_POSITION']);
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$realName = null;
$constraints = [];
foreach ($results->toArray() as $row) {
if ($row['CONSTRAINT_NAME'] !== $realName) {
$realName = $row['CONSTRAINT_NAME'];
$isFK = ('FOREIGN KEY' == $row['CONSTRAINT_TYPE']);
if ($isFK) {
$name = $realName;
} else {
$name = '_zf_' . $row['TABLE_NAME'] . '_' . $realName;
}
$constraints[$name] = [
'constraint_name' => $name,
'constraint_type' => $row['CONSTRAINT_TYPE'],
'table_name' => $row['TABLE_NAME'],
'columns' => [],
];
if ($isFK) {
$constraints[$name]['referenced_table_schema'] = $row['REFERENCED_TABLE_SCHEMA'];
$constraints[$name]['referenced_table_name'] = $row['REFERENCED_TABLE_NAME'];
$constraints[$name]['referenced_columns'] = [];
$constraints[$name]['match_option'] = $row['MATCH_OPTION'];
$constraints[$name]['update_rule'] = $row['UPDATE_RULE'];
$constraints[$name]['delete_rule'] = $row['DELETE_RULE'];
}
}
$constraints[$name]['columns'][] = $row['COLUMN_NAME'];
if ($isFK) {
$constraints[$name]['referenced_columns'][] = $row['REFERENCED_COLUMN_NAME'];
}
}
$this->data['constraints'][$schema][$table] = $constraints;
}
protected function loadConstraintDataNames($schema)
{
if (isset($this->data['constraint_names'][$schema])) {
return;
}
$this->prepareDataHierarchy('constraint_names', $schema);
$p = $this->adapter->getPlatform();
$isColumns = [
['TC', 'TABLE_NAME'],
['TC', 'CONSTRAINT_NAME'],
['TC', 'CONSTRAINT_TYPE'],
];
array_walk($isColumns, function (&$c) use ($p) {
$c = $p->quoteIdentifierChain($c);
});
$sql = 'SELECT ' . implode(', ', $isColumns)
. ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLES']) . 'T'
. ' INNER JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLE_CONSTRAINTS']) . 'TC'
. ' ON ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' = ' . $p->quoteIdentifierChain(['TC', 'TABLE_SCHEMA'])
. ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME'])
. ' = ' . $p->quoteIdentifierChain(['TC', 'TABLE_NAME'])
. ' WHERE ' . $p->quoteIdentifierChain(['T', 'TABLE_TYPE'])
. ' IN (\'BASE TABLE\', \'VIEW\')';
if ($schema != self::DEFAULT_SCHEMA) {
$sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' = ' . $p->quoteTrustedValue($schema);
} else {
$sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' != \'INFORMATION_SCHEMA\'';
}
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$data = [];
foreach ($results->toArray() as $row) {
$data[] = array_change_key_case($row, CASE_LOWER);
}
$this->data['constraint_names'][$schema] = $data;
}
protected function loadConstraintDataKeys($schema)
{
if (isset($this->data['constraint_keys'][$schema])) {
return;
}
$this->prepareDataHierarchy('constraint_keys', $schema);
$p = $this->adapter->getPlatform();
$isColumns = [
['T', 'TABLE_NAME'],
['KCU', 'CONSTRAINT_NAME'],
['KCU', 'COLUMN_NAME'],
['KCU', 'ORDINAL_POSITION'],
];
array_walk($isColumns, function (&$c) use ($p) {
$c = $p->quoteIdentifierChain($c);
});
$sql = 'SELECT ' . implode(', ', $isColumns)
. ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLES']) . 'T'
. ' INNER JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'KEY_COLUMN_USAGE']) . 'KCU'
. ' ON ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' = ' . $p->quoteIdentifierChain(['KCU', 'TABLE_SCHEMA'])
. ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME'])
. ' = ' . $p->quoteIdentifierChain(['KCU', 'TABLE_NAME'])
. ' WHERE ' . $p->quoteIdentifierChain(['T', 'TABLE_TYPE'])
. ' IN (\'BASE TABLE\', \'VIEW\')';
if ($schema != self::DEFAULT_SCHEMA) {
$sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' = ' . $p->quoteTrustedValue($schema);
} else {
$sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' != \'INFORMATION_SCHEMA\'';
}
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$data = [];
foreach ($results->toArray() as $row) {
$data[] = array_change_key_case($row, CASE_LOWER);
}
$this->data['constraint_keys'][$schema] = $data;
}
protected function loadConstraintReferences($table, $schema)
{
parent::loadConstraintReferences($table, $schema);
$p = $this->adapter->getPlatform();
$isColumns = [
['RC', 'TABLE_NAME'],
['RC', 'CONSTRAINT_NAME'],
['RC', 'UPDATE_RULE'],
['RC', 'DELETE_RULE'],
['KCU', 'REFERENCED_TABLE_SCHEMA'],
['KCU', 'REFERENCED_TABLE_NAME'],
['KCU', 'REFERENCED_COLUMN_NAME'],
];
array_walk($isColumns, function (&$c) use ($p) {
$c = $p->quoteIdentifierChain($c);
});
$sql = 'SELECT ' . implode(', ', $isColumns)
. 'FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLES']) . 'T'
. ' INNER JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'REFERENTIAL_CONSTRAINTS']) . 'RC'
. ' ON ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' = ' . $p->quoteIdentifierChain(['RC', 'CONSTRAINT_SCHEMA'])
. ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME'])
. ' = ' . $p->quoteIdentifierChain(['RC', 'TABLE_NAME'])
. ' INNER JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'KEY_COLUMN_USAGE']) . 'KCU'
. ' ON ' . $p->quoteIdentifierChain(['RC', 'CONSTRAINT_SCHEMA'])
. ' = ' . $p->quoteIdentifierChain(['KCU', 'TABLE_SCHEMA'])
. ' AND ' . $p->quoteIdentifierChain(['RC', 'TABLE_NAME'])
. ' = ' . $p->quoteIdentifierChain(['KCU', 'TABLE_NAME'])
. ' AND ' . $p->quoteIdentifierChain(['RC', 'CONSTRAINT_NAME'])
. ' = ' . $p->quoteIdentifierChain(['KCU', 'CONSTRAINT_NAME'])
. 'WHERE ' . $p->quoteIdentifierChain(['T', 'TABLE_TYPE'])
. ' IN (\'BASE TABLE\', \'VIEW\')';
if ($schema != self::DEFAULT_SCHEMA) {
$sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' = ' . $p->quoteTrustedValue($schema);
} else {
$sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' != \'INFORMATION_SCHEMA\'';
}
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$data = [];
foreach ($results->toArray() as $row) {
$data[] = array_change_key_case($row, CASE_LOWER);
}
$this->data['constraint_references'][$schema] = $data;
}
protected function loadTriggerData($schema)
{
if (isset($this->data['triggers'][$schema])) {
return;
}
$this->prepareDataHierarchy('triggers', $schema);
$p = $this->adapter->getPlatform();
$isColumns = [
// 'TRIGGER_CATALOG',
// 'TRIGGER_SCHEMA',
'TRIGGER_NAME',
'EVENT_MANIPULATION',
'EVENT_OBJECT_CATALOG',
'EVENT_OBJECT_SCHEMA',
'EVENT_OBJECT_TABLE',
'ACTION_ORDER',
'ACTION_CONDITION',
'ACTION_STATEMENT',
'ACTION_ORIENTATION',
'ACTION_TIMING',
'ACTION_REFERENCE_OLD_TABLE',
'ACTION_REFERENCE_NEW_TABLE',
'ACTION_REFERENCE_OLD_ROW',
'ACTION_REFERENCE_NEW_ROW',
'CREATED',
];
array_walk($isColumns, function (&$c) use ($p) {
$c = $p->quoteIdentifier($c);
});
$sql = 'SELECT ' . implode(', ', $isColumns)
. ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TRIGGERS'])
. ' WHERE ';
if ($schema != self::DEFAULT_SCHEMA) {
$sql .= $p->quoteIdentifier('TRIGGER_SCHEMA')
. ' = ' . $p->quoteTrustedValue($schema);
} else {
$sql .= $p->quoteIdentifier('TRIGGER_SCHEMA')
. ' != \'INFORMATION_SCHEMA\'';
}
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$data = [];
foreach ($results->toArray() as $row) {
$row = array_change_key_case($row, CASE_LOWER);
if (null !== $row['created']) {
$row['created'] = new \DateTime($row['created']);
}
$data[$row['trigger_name']] = $row;
}
$this->data['triggers'][$schema] = $data;
}
}
================================================
FILE: src/Zend/Db/src/Metadata/Source/OracleMetadata.php
================================================
'CHECK',
'P' => 'PRIMARY KEY',
'R' => 'FOREIGN_KEY'
];
/**
* {@inheritdoc}
* @see \Zend\Db\Metadata\Source\AbstractSource::loadColumnData()
*/
protected function loadColumnData($table, $schema)
{
if (isset($this->data['columns'][$schema][$table])) {
return;
}
$isColumns = [
'COLUMN_ID',
'COLUMN_NAME',
'DATA_DEFAULT',
'NULLABLE',
'DATA_TYPE',
'DATA_LENGTH',
'DATA_PRECISION',
'DATA_SCALE'
];
$this->prepareDataHierarchy('columns', $schema, $table);
$parameters = [
':ownername' => $schema,
':tablename' => $table
];
$sql = 'SELECT ' . implode(', ', $isColumns)
. ' FROM all_tab_columns'
. ' WHERE owner = :ownername AND table_name = :tablename';
$result = $this->adapter->query($sql)->execute($parameters);
$columns = [];
foreach ($result as $row) {
$columns[$row['COLUMN_NAME']] = [
'ordinal_position' => $row['COLUMN_ID'],
'column_default' => $row['DATA_DEFAULT'],
'is_nullable' => ('Y' == $row['NULLABLE']),
'data_type' => $row['DATA_TYPE'],
'character_maximum_length' => $row['DATA_LENGTH'],
'character_octet_length' => null,
'numeric_precision' => $row['DATA_PRECISION'],
'numeric_scale' => $row['DATA_SCALE'],
'numeric_unsigned' => false,
'erratas' => [],
];
}
$this->data['columns'][$schema][$table] = $columns;
return $this;
}
/**
* Constraint type
*
* @param string $type
* @return string
*/
protected function getConstraintType($type)
{
if (isset($this->constraintTypeMap[$type])) {
return $this->constraintTypeMap[$type];
}
return $type;
}
/**
* {@inheritdoc}
* @see \Zend\Db\Metadata\Source\AbstractSource::loadConstraintData()
*/
protected function loadConstraintData($table, $schema)
{
if (isset($this->data['constraints'][$schema][$table])) {
return;
}
$this->prepareDataHierarchy('constraints', $schema, $table);
$sql = '
SELECT
ac.owner,
ac.constraint_name,
ac.constraint_type,
ac.search_condition check_clause,
ac.table_name,
ac.delete_rule,
cc1.column_name,
cc2.table_name as ref_table,
cc2.column_name as ref_column,
cc2.owner as ref_owner
FROM all_constraints ac
INNER JOIN all_cons_columns cc1
ON cc1.constraint_name = ac.constraint_name
LEFT JOIN all_cons_columns cc2
ON cc2.constraint_name = ac.r_constraint_name
AND cc2.position = cc1.position
WHERE
ac.owner = :ownername AND ac.table_name = :tablename
ORDER BY ac.constraint_name
';
$parameters = [
':ownername' => $schema,
':tablename' => $table
];
$results = $this->adapter->query($sql)->execute($parameters);
$isFK = false;
$name = null;
$constraints = [];
foreach ($results as $row) {
if ($row['CONSTRAINT_NAME'] !== $name) {
$name = $row['CONSTRAINT_NAME'];
$constraints[$name] = [
'constraint_name' => $name,
'constraint_type' => $this->getConstraintType($row['CONSTRAINT_TYPE']),
'table_name' => $row['TABLE_NAME'],
];
if ('C' == $row['CONSTRAINT_TYPE']) {
$constraints[$name]['CHECK_CLAUSE'] = $row['CHECK_CLAUSE'];
continue;
}
$constraints[$name]['columns'] = [];
$isFK = ('R' == $row['CONSTRAINT_TYPE']);
if ($isFK) {
$constraints[$name]['referenced_table_schema'] = $row['REF_OWNER'];
$constraints[$name]['referenced_table_name'] = $row['REF_TABLE'];
$constraints[$name]['referenced_columns'] = [];
$constraints[$name]['match_option'] = 'NONE';
$constraints[$name]['update_rule'] = null;
$constraints[$name]['delete_rule'] = $row['DELETE_RULE'];
}
}
$constraints[$name]['columns'][] = $row['COLUMN_NAME'];
if ($isFK) {
$constraints[$name]['referenced_columns'][] = $row['REF_COLUMN'];
}
}
$this->data['constraints'][$schema][$table] = $constraints;
return $this;
}
/**
* {@inheritdoc}
* @see \Zend\Db\Metadata\Source\AbstractSource::loadSchemaData()
*/
protected function loadSchemaData()
{
if (isset($this->data['schemas'])) {
return;
}
$this->prepareDataHierarchy('schemas');
$sql = 'SELECT USERNAME FROM ALL_USERS';
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$schemas = [];
foreach ($results->toArray() as $row) {
$schemas[] = $row['USERNAME'];
}
$this->data['schemas'] = $schemas;
}
/**
* {@inheritdoc}
* @see \Zend\Db\Metadata\Source\AbstractSource::loadTableNameData()
*/
protected function loadTableNameData($schema)
{
if (isset($this->data['table_names'][$schema])) {
return $this;
}
$this->prepareDataHierarchy('table_names', $schema);
$tables = [];
// Tables
$bind = [':OWNER' => strtoupper($schema)];
$result = $this->adapter->query('SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER=:OWNER')->execute($bind);
foreach ($result as $row) {
$tables[$row['TABLE_NAME']] = [
'table_type' => 'BASE TABLE',
'view_definition' => null,
'check_option' => null,
'is_updatable' => false,
];
}
// Views
$result = $this->adapter->query('SELECT VIEW_NAME, TEXT FROM ALL_VIEWS WHERE OWNER=:OWNER', $bind);
foreach ($result as $row) {
$tables[$row['VIEW_NAME']] = [
'table_type' => 'VIEW',
'view_definition' => null,
'check_option' => 'NONE',
'is_updatable' => false,
];
}
$this->data['table_names'][$schema] = $tables;
return $this;
}
/**
* FIXME: load trigger data
*
* {@inheritdoc}
*
* @see \Zend\Db\Metadata\Source\AbstractSource::loadTriggerData()
*/
protected function loadTriggerData($schema)
{
if (isset($this->data['triggers'][$schema])) {
return;
}
$this->prepareDataHierarchy('triggers', $schema);
}
}
================================================
FILE: src/Zend/Db/src/Metadata/Source/PostgresqlMetadata.php
================================================
data['schemas'])) {
return;
}
$this->prepareDataHierarchy('schemas');
$p = $this->adapter->getPlatform();
$sql = 'SELECT ' . $p->quoteIdentifier('schema_name')
. ' FROM ' . $p->quoteIdentifierChain(['information_schema', 'schemata'])
. ' WHERE ' . $p->quoteIdentifier('schema_name')
. ' != \'information_schema\''
. ' AND ' . $p->quoteIdentifier('schema_name') . " NOT LIKE 'pg_%'";
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$schemas = [];
foreach ($results->toArray() as $row) {
$schemas[] = $row['schema_name'];
}
$this->data['schemas'] = $schemas;
}
protected function loadTableNameData($schema)
{
if (isset($this->data['table_names'][$schema])) {
return;
}
$this->prepareDataHierarchy('table_names', $schema);
$p = $this->adapter->getPlatform();
$isColumns = [
['t', 'table_name'],
['t', 'table_type'],
['v', 'view_definition'],
['v', 'check_option'],
['v', 'is_updatable'],
];
array_walk($isColumns, function (&$c) use ($p) {
$c = $p->quoteIdentifierChain($c);
});
$sql = 'SELECT ' . implode(', ', $isColumns)
. ' FROM ' . $p->quoteIdentifierChain(['information_schema', 'tables']) . ' t'
. ' LEFT JOIN ' . $p->quoteIdentifierChain(['information_schema', 'views']) . ' v'
. ' ON ' . $p->quoteIdentifierChain(['t', 'table_schema'])
. ' = ' . $p->quoteIdentifierChain(['v', 'table_schema'])
. ' AND ' . $p->quoteIdentifierChain(['t', 'table_name'])
. ' = ' . $p->quoteIdentifierChain(['v', 'table_name'])
. ' WHERE ' . $p->quoteIdentifierChain(['t', 'table_type'])
. ' IN (\'BASE TABLE\', \'VIEW\')';
if ($schema != self::DEFAULT_SCHEMA) {
$sql .= ' AND ' . $p->quoteIdentifierChain(['t', 'table_schema'])
. ' = ' . $p->quoteTrustedValue($schema);
} else {
$sql .= ' AND ' . $p->quoteIdentifierChain(['t', 'table_schema'])
. ' != \'information_schema\'';
}
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$tables = [];
foreach ($results->toArray() as $row) {
$tables[$row['table_name']] = [
'table_type' => $row['table_type'],
'view_definition' => $row['view_definition'],
'check_option' => $row['check_option'],
'is_updatable' => ('YES' == $row['is_updatable']),
];
}
$this->data['table_names'][$schema] = $tables;
}
protected function loadColumnData($table, $schema)
{
if (isset($this->data['columns'][$schema][$table])) {
return;
}
$this->prepareDataHierarchy('columns', $schema, $table);
$platform = $this->adapter->getPlatform();
$isColumns = [
'table_name',
'column_name',
'ordinal_position',
'column_default',
'is_nullable',
'data_type',
'character_maximum_length',
'character_octet_length',
'numeric_precision',
'numeric_scale',
];
array_walk($isColumns, function (&$c) use ($platform) {
$c = $platform->quoteIdentifier($c);
});
$sql = 'SELECT ' . implode(', ', $isColumns)
. ' FROM ' . $platform->quoteIdentifier('information_schema')
. $platform->getIdentifierSeparator() . $platform->quoteIdentifier('columns')
. ' WHERE ' . $platform->quoteIdentifier('table_schema')
. ' != \'information\''
. ' AND ' . $platform->quoteIdentifier('table_name')
. ' = ' . $platform->quoteTrustedValue($table);
if ($schema != '__DEFAULT_SCHEMA__') {
$sql .= ' AND ' . $platform->quoteIdentifier('table_schema')
. ' = ' . $platform->quoteTrustedValue($schema);
}
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$columns = [];
foreach ($results->toArray() as $row) {
$columns[$row['column_name']] = [
'ordinal_position' => $row['ordinal_position'],
'column_default' => $row['column_default'],
'is_nullable' => ('YES' == $row['is_nullable']),
'data_type' => $row['data_type'],
'character_maximum_length' => $row['character_maximum_length'],
'character_octet_length' => $row['character_octet_length'],
'numeric_precision' => $row['numeric_precision'],
'numeric_scale' => $row['numeric_scale'],
'numeric_unsigned' => null,
'erratas' => [],
];
}
$this->data['columns'][$schema][$table] = $columns;
}
protected function loadConstraintData($table, $schema)
{
if (isset($this->data['constraints'][$schema][$table])) {
return;
}
$this->prepareDataHierarchy('constraints', $schema, $table);
$isColumns = [
['t', 'table_name'],
['tc', 'constraint_name'],
['tc', 'constraint_type'],
['kcu', 'column_name'],
['cc', 'check_clause'],
['rc', 'match_option'],
['rc', 'update_rule'],
['rc', 'delete_rule'],
['referenced_table_schema' => 'kcu2', 'table_schema'],
['referenced_table_name' => 'kcu2', 'table_name'],
['referenced_column_name' => 'kcu2', 'column_name'],
];
$p = $this->adapter->getPlatform();
array_walk($isColumns, function (&$c) use ($p) {
$alias = key($c);
$c = $p->quoteIdentifierChain($c);
if (is_string($alias)) {
$c .= ' ' . $p->quoteIdentifier($alias);
}
});
$sql = 'SELECT ' . implode(', ', $isColumns)
. ' FROM ' . $p->quoteIdentifierChain(['information_schema', 'tables']) . ' t'
. ' INNER JOIN ' . $p->quoteIdentifierChain(['information_schema', 'table_constraints']) . ' tc'
. ' ON ' . $p->quoteIdentifierChain(['t', 'table_schema'])
. ' = ' . $p->quoteIdentifierChain(['tc', 'table_schema'])
. ' AND ' . $p->quoteIdentifierChain(['t', 'table_name'])
. ' = ' . $p->quoteIdentifierChain(['tc', 'table_name'])
. ' LEFT JOIN ' . $p->quoteIdentifierChain(['information_schema', 'key_column_usage']) . ' kcu'
. ' ON ' . $p->quoteIdentifierChain(['tc', 'table_schema'])
. ' = ' . $p->quoteIdentifierChain(['kcu', 'table_schema'])
. ' AND ' . $p->quoteIdentifierChain(['tc', 'table_name'])
. ' = ' . $p->quoteIdentifierChain(['kcu', 'table_name'])
. ' AND ' . $p->quoteIdentifierChain(['tc', 'constraint_name'])
. ' = ' . $p->quoteIdentifierChain(['kcu', 'constraint_name'])
. ' LEFT JOIN ' . $p->quoteIdentifierChain(['information_schema', 'check_constraints']) . ' cc'
. ' ON ' . $p->quoteIdentifierChain(['tc', 'constraint_schema'])
. ' = ' . $p->quoteIdentifierChain(['cc', 'constraint_schema'])
. ' AND ' . $p->quoteIdentifierChain(['tc', 'constraint_name'])
. ' = ' . $p->quoteIdentifierChain(['cc', 'constraint_name'])
. ' LEFT JOIN ' . $p->quoteIdentifierChain(['information_schema', 'referential_constraints']) . ' rc'
. ' ON ' . $p->quoteIdentifierChain(['tc', 'constraint_schema'])
. ' = ' . $p->quoteIdentifierChain(['rc', 'constraint_schema'])
. ' AND ' . $p->quoteIdentifierChain(['tc', 'constraint_name'])
. ' = ' . $p->quoteIdentifierChain(['rc', 'constraint_name'])
. ' LEFT JOIN ' . $p->quoteIdentifierChain(['information_schema', 'key_column_usage']) . ' kcu2'
. ' ON ' . $p->quoteIdentifierChain(['rc', 'unique_constraint_schema'])
. ' = ' . $p->quoteIdentifierChain(['kcu2', 'constraint_schema'])
. ' AND ' . $p->quoteIdentifierChain(['rc', 'unique_constraint_name'])
. ' = ' . $p->quoteIdentifierChain(['kcu2', 'constraint_name'])
. ' AND ' . $p->quoteIdentifierChain(['kcu', 'position_in_unique_constraint'])
. ' = ' . $p->quoteIdentifierChain(['kcu2', 'ordinal_position'])
. ' WHERE ' . $p->quoteIdentifierChain(['t', 'table_name'])
. ' = ' . $p->quoteTrustedValue($table)
. ' AND ' . $p->quoteIdentifierChain(['t', 'table_type'])
. ' IN (\'BASE TABLE\', \'VIEW\')';
if ($schema != self::DEFAULT_SCHEMA) {
$sql .= ' AND ' . $p->quoteIdentifierChain(['t', 'table_schema'])
. ' = ' . $p->quoteTrustedValue($schema);
} else {
$sql .= ' AND ' . $p->quoteIdentifierChain(['t', 'table_schema'])
. ' != \'information_schema\'';
}
$sql .= ' ORDER BY CASE ' . $p->quoteIdentifierChain(['tc', 'constraint_type'])
. " WHEN 'PRIMARY KEY' THEN 1"
. " WHEN 'UNIQUE' THEN 2"
. " WHEN 'FOREIGN KEY' THEN 3"
. " WHEN 'CHECK' THEN 4"
. " ELSE 5 END"
. ', ' . $p->quoteIdentifierChain(['tc', 'constraint_name'])
. ', ' . $p->quoteIdentifierChain(['kcu', 'ordinal_position']);
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$name = null;
$constraints = [];
foreach ($results->toArray() as $row) {
if ($row['constraint_name'] !== $name) {
$name = $row['constraint_name'];
$constraints[$name] = [
'constraint_name' => $name,
'constraint_type' => $row['constraint_type'],
'table_name' => $row['table_name'],
];
if ('CHECK' == $row['constraint_type']) {
$constraints[$name]['check_clause'] = $row['check_clause'];
continue;
}
$constraints[$name]['columns'] = [];
$isFK = ('FOREIGN KEY' == $row['constraint_type']);
if ($isFK) {
$constraints[$name]['referenced_table_schema'] = $row['referenced_table_schema'];
$constraints[$name]['referenced_table_name'] = $row['referenced_table_name'];
$constraints[$name]['referenced_columns'] = [];
$constraints[$name]['match_option'] = $row['match_option'];
$constraints[$name]['update_rule'] = $row['update_rule'];
$constraints[$name]['delete_rule'] = $row['delete_rule'];
}
}
$constraints[$name]['columns'][] = $row['column_name'];
if ($isFK) {
$constraints[$name]['referenced_columns'][] = $row['referenced_column_name'];
}
}
$this->data['constraints'][$schema][$table] = $constraints;
}
protected function loadTriggerData($schema)
{
if (isset($this->data['triggers'][$schema])) {
return;
}
$this->prepareDataHierarchy('triggers', $schema);
$p = $this->adapter->getPlatform();
$isColumns = [
'trigger_name',
'event_manipulation',
'event_object_catalog',
'event_object_schema',
'event_object_table',
'action_order',
'action_condition',
'action_statement',
'action_orientation',
['action_timing' => 'condition_timing'],
['action_reference_old_table' => 'condition_reference_old_table'],
['action_reference_new_table' => 'condition_reference_new_table'],
'created',
];
array_walk($isColumns, function (&$c) use ($p) {
if (is_array($c)) {
$alias = key($c);
$c = $p->quoteIdentifierChain($c);
if (is_string($alias)) {
$c .= ' ' . $p->quoteIdentifier($alias);
}
} else {
$c = $p->quoteIdentifier($c);
}
});
$sql = 'SELECT ' . implode(', ', $isColumns)
. ' FROM ' . $p->quoteIdentifierChain(['information_schema', 'triggers'])
. ' WHERE ';
if ($schema != self::DEFAULT_SCHEMA) {
$sql .= $p->quoteIdentifier('trigger_schema')
. ' = ' . $p->quoteTrustedValue($schema);
} else {
$sql .= $p->quoteIdentifier('trigger_schema')
. ' != \'information_schema\'';
}
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$data = [];
foreach ($results->toArray() as $row) {
$row = array_change_key_case($row, CASE_LOWER);
$row['action_reference_old_row'] = 'OLD';
$row['action_reference_new_row'] = 'NEW';
if (null !== $row['created']) {
$row['created'] = new \DateTime($row['created']);
}
$data[$row['trigger_name']] = $row;
}
$this->data['triggers'][$schema] = $data;
}
}
================================================
FILE: src/Zend/Db/src/Metadata/Source/SqlServerMetadata.php
================================================
data['schemas'])) {
return;
}
$this->prepareDataHierarchy('schemas');
$p = $this->adapter->getPlatform();
$sql = 'SELECT ' . $p->quoteIdentifier('SCHEMA_NAME')
. ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'SCHEMATA'])
. ' WHERE ' . $p->quoteIdentifier('SCHEMA_NAME')
. ' != \'INFORMATION_SCHEMA\'';
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$schemas = [];
foreach ($results->toArray() as $row) {
$schemas[] = $row['SCHEMA_NAME'];
}
$this->data['schemas'] = $schemas;
}
protected function loadTableNameData($schema)
{
if (isset($this->data['table_names'][$schema])) {
return;
}
$this->prepareDataHierarchy('table_names', $schema);
$p = $this->adapter->getPlatform();
$isColumns = [
['T', 'TABLE_NAME'],
['T', 'TABLE_TYPE'],
['V', 'VIEW_DEFINITION'],
['V', 'CHECK_OPTION'],
['V', 'IS_UPDATABLE'],
];
array_walk($isColumns, function (&$c) use ($p) {
$c = $p->quoteIdentifierChain($c);
});
$sql = 'SELECT ' . implode(', ', $isColumns)
. ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLES']) . ' t'
. ' LEFT JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'VIEWS']) . ' v'
. ' ON ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' = ' . $p->quoteIdentifierChain(['V', 'TABLE_SCHEMA'])
. ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME'])
. ' = ' . $p->quoteIdentifierChain(['V', 'TABLE_NAME'])
. ' WHERE ' . $p->quoteIdentifierChain(['T', 'TABLE_TYPE'])
. ' IN (\'BASE TABLE\', \'VIEW\')';
if ($schema != self::DEFAULT_SCHEMA) {
$sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' = ' . $p->quoteTrustedValue($schema);
} else {
$sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' != \'INFORMATION_SCHEMA\'';
}
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$tables = [];
foreach ($results->toArray() as $row) {
$tables[$row['TABLE_NAME']] = [
'table_type' => $row['TABLE_TYPE'],
'view_definition' => $row['VIEW_DEFINITION'],
'check_option' => $row['CHECK_OPTION'],
'is_updatable' => ('YES' == $row['IS_UPDATABLE']),
];
}
$this->data['table_names'][$schema] = $tables;
}
protected function loadColumnData($table, $schema)
{
if (isset($this->data['columns'][$schema][$table])) {
return;
}
$this->prepareDataHierarchy('columns', $schema, $table);
$p = $this->adapter->getPlatform();
$isColumns = [
['C', 'ORDINAL_POSITION'],
['C', 'COLUMN_DEFAULT'],
['C', 'IS_NULLABLE'],
['C', 'DATA_TYPE'],
['C', 'CHARACTER_MAXIMUM_LENGTH'],
['C', 'CHARACTER_OCTET_LENGTH'],
['C', 'NUMERIC_PRECISION'],
['C', 'NUMERIC_SCALE'],
['C', 'COLUMN_NAME'],
];
array_walk($isColumns, function (&$c) use ($p) {
$c = $p->quoteIdentifierChain($c);
});
$sql = 'SELECT ' . implode(', ', $isColumns)
. ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLES']) . 'T'
. ' INNER JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'COLUMNS']) . 'C'
. ' ON ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' = ' . $p->quoteIdentifierChain(['C', 'TABLE_SCHEMA'])
. ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME'])
. ' = ' . $p->quoteIdentifierChain(['C', 'TABLE_NAME'])
. ' WHERE ' . $p->quoteIdentifierChain(['T', 'TABLE_TYPE'])
. ' IN (\'BASE TABLE\', \'VIEW\')'
. ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME'])
. ' = ' . $p->quoteTrustedValue($table);
if ($schema != self::DEFAULT_SCHEMA) {
$sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' = ' . $p->quoteTrustedValue($schema);
} else {
$sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' != \'INFORMATION_SCHEMA\'';
}
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$columns = [];
foreach ($results->toArray() as $row) {
$columns[$row['COLUMN_NAME']] = [
'ordinal_position' => $row['ORDINAL_POSITION'],
'column_default' => $row['COLUMN_DEFAULT'],
'is_nullable' => ('YES' == $row['IS_NULLABLE']),
'data_type' => $row['DATA_TYPE'],
'character_maximum_length' => $row['CHARACTER_MAXIMUM_LENGTH'],
'character_octet_length' => $row['CHARACTER_OCTET_LENGTH'],
'numeric_precision' => $row['NUMERIC_PRECISION'],
'numeric_scale' => $row['NUMERIC_SCALE'],
'numeric_unsigned' => null,
'erratas' => [],
];
}
$this->data['columns'][$schema][$table] = $columns;
}
protected function loadConstraintData($table, $schema)
{
if (isset($this->data['constraints'][$schema][$table])) {
return;
}
$this->prepareDataHierarchy('constraints', $schema, $table);
$isColumns = [
['T', 'TABLE_NAME'],
['TC', 'CONSTRAINT_NAME'],
['TC', 'CONSTRAINT_TYPE'],
['KCU', 'COLUMN_NAME'],
['CC', 'CHECK_CLAUSE'],
['RC', 'MATCH_OPTION'],
['RC', 'UPDATE_RULE'],
['RC', 'DELETE_RULE'],
['REFERENCED_TABLE_SCHEMA' => 'KCU2', 'TABLE_SCHEMA'],
['REFERENCED_TABLE_NAME' => 'KCU2', 'TABLE_NAME'],
['REFERENCED_COLUMN_NAME' => 'KCU2', 'COLUMN_NAME'],
];
$p = $this->adapter->getPlatform();
array_walk($isColumns, function (&$c) use ($p) {
$alias = key($c);
$c = $p->quoteIdentifierChain($c);
if (is_string($alias)) {
$c .= ' ' . $p->quoteIdentifier($alias);
}
});
$sql = 'SELECT ' . implode(', ', $isColumns)
. ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLES']) . ' T'
. ' INNER JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TABLE_CONSTRAINTS']) . ' TC'
. ' ON ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' = ' . $p->quoteIdentifierChain(['TC', 'TABLE_SCHEMA'])
. ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME'])
. ' = ' . $p->quoteIdentifierChain(['TC', 'TABLE_NAME'])
. ' LEFT JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'KEY_COLUMN_USAGE']) . ' KCU'
. ' ON ' . $p->quoteIdentifierChain(['TC', 'TABLE_SCHEMA'])
. ' = ' . $p->quoteIdentifierChain(['KCU', 'TABLE_SCHEMA'])
. ' AND ' . $p->quoteIdentifierChain(['TC', 'TABLE_NAME'])
. ' = ' . $p->quoteIdentifierChain(['KCU', 'TABLE_NAME'])
. ' AND ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_NAME'])
. ' = ' . $p->quoteIdentifierChain(['KCU', 'CONSTRAINT_NAME'])
. ' LEFT JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'CHECK_CONSTRAINTS']) . ' CC'
. ' ON ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_SCHEMA'])
. ' = ' . $p->quoteIdentifierChain(['CC', 'CONSTRAINT_SCHEMA'])
. ' AND ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_NAME'])
. ' = ' . $p->quoteIdentifierChain(['CC', 'CONSTRAINT_NAME'])
. ' LEFT JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'REFERENTIAL_CONSTRAINTS']) . ' RC'
. ' ON ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_SCHEMA'])
. ' = ' . $p->quoteIdentifierChain(['RC', 'CONSTRAINT_SCHEMA'])
. ' AND ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_NAME'])
. ' = ' . $p->quoteIdentifierChain(['RC', 'CONSTRAINT_NAME'])
. ' LEFT JOIN ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'KEY_COLUMN_USAGE']) . ' KCU2'
. ' ON ' . $p->quoteIdentifierChain(['RC', 'UNIQUE_CONSTRAINT_SCHEMA'])
. ' = ' . $p->quoteIdentifierChain(['KCU2', 'CONSTRAINT_SCHEMA'])
. ' AND ' . $p->quoteIdentifierChain(['RC', 'UNIQUE_CONSTRAINT_NAME'])
. ' = ' . $p->quoteIdentifierChain(['KCU2', 'CONSTRAINT_NAME'])
. ' AND ' . $p->quoteIdentifierChain(['KCU', 'ORDINAL_POSITION'])
. ' = ' . $p->quoteIdentifierChain(['KCU2', 'ORDINAL_POSITION'])
. ' WHERE ' . $p->quoteIdentifierChain(['T', 'TABLE_NAME'])
. ' = ' . $p->quoteTrustedValue($table)
. ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_TYPE'])
. ' IN (\'BASE TABLE\', \'VIEW\')';
if ($schema != self::DEFAULT_SCHEMA) {
$sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' = ' . $p->quoteTrustedValue($schema);
} else {
$sql .= ' AND ' . $p->quoteIdentifierChain(['T', 'TABLE_SCHEMA'])
. ' != \'INFORMATION_SCHEMA\'';
}
$sql .= ' ORDER BY CASE ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_TYPE'])
. " WHEN 'PRIMARY KEY' THEN 1"
. " WHEN 'UNIQUE' THEN 2"
. " WHEN 'FOREIGN KEY' THEN 3"
. " WHEN 'CHECK' THEN 4"
. " ELSE 5 END"
. ', ' . $p->quoteIdentifierChain(['TC', 'CONSTRAINT_NAME'])
. ', ' . $p->quoteIdentifierChain(['KCU', 'ORDINAL_POSITION']);
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$name = null;
$constraints = [];
$isFK = false;
foreach ($results->toArray() as $row) {
if ($row['CONSTRAINT_NAME'] !== $name) {
$name = $row['CONSTRAINT_NAME'];
$constraints[$name] = [
'constraint_name' => $name,
'constraint_type' => $row['CONSTRAINT_TYPE'],
'table_name' => $row['TABLE_NAME'],
];
if ('CHECK' == $row['CONSTRAINT_TYPE']) {
$constraints[$name]['check_clause'] = $row['CHECK_CLAUSE'];
continue;
}
$constraints[$name]['columns'] = [];
$isFK = ('FOREIGN KEY' == $row['CONSTRAINT_TYPE']);
if ($isFK) {
$constraints[$name]['referenced_table_schema'] = $row['REFERENCED_TABLE_SCHEMA'];
$constraints[$name]['referenced_table_name'] = $row['REFERENCED_TABLE_NAME'];
$constraints[$name]['referenced_columns'] = [];
$constraints[$name]['match_option'] = $row['MATCH_OPTION'];
$constraints[$name]['update_rule'] = $row['UPDATE_RULE'];
$constraints[$name]['delete_rule'] = $row['DELETE_RULE'];
}
}
$constraints[$name]['columns'][] = $row['COLUMN_NAME'];
if ($isFK) {
$constraints[$name]['referenced_columns'][] = $row['REFERENCED_COLUMN_NAME'];
}
}
$this->data['constraints'][$schema][$table] = $constraints;
}
protected function loadTriggerData($schema)
{
if (isset($this->data['triggers'][$schema])) {
return;
}
$this->prepareDataHierarchy('triggers', $schema);
$p = $this->adapter->getPlatform();
$isColumns = [
'TRIGGER_NAME',
'EVENT_MANIPULATION',
'EVENT_OBJECT_CATALOG',
'EVENT_OBJECT_SCHEMA',
'EVENT_OBJECT_TABLE',
'ACTION_ORDER',
'ACTION_CONDITION',
'ACTION_STATEMENT',
'ACTION_ORIENTATION',
'ACTION_TIMING',
'ACTION_REFERENCE_OLD_TABLE',
'ACTION_REFERENCE_NEW_TABLE',
'ACTION_REFERENCE_OLD_ROW',
'ACTION_REFERENCE_NEW_ROW',
'CREATED',
];
array_walk($isColumns, function (&$c) use ($p) {
$c = $p->quoteIdentifier($c);
});
$sql = 'SELECT ' . implode(', ', $isColumns)
. ' FROM ' . $p->quoteIdentifierChain(['INFORMATION_SCHEMA', 'TRIGGERS'])
. ' WHERE ';
if ($schema != self::DEFAULT_SCHEMA) {
$sql .= $p->quoteIdentifier('TRIGGER_SCHEMA')
. ' = ' . $p->quoteTrustedValue($schema);
} else {
$sql .= $p->quoteIdentifier('TRIGGER_SCHEMA')
. ' != \'INFORMATION_SCHEMA\'';
}
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$data = [];
foreach ($results->toArray() as $row) {
$row = array_change_key_case($row, CASE_LOWER);
if (null !== $row['created']) {
$row['created'] = new \DateTime($row['created']);
}
$data[$row['trigger_name']] = $row;
}
$this->data['triggers'][$schema] = $data;
}
}
================================================
FILE: src/Zend/Db/src/Metadata/Source/SqliteMetadata.php
================================================
data['schemas'])) {
return;
}
$this->prepareDataHierarchy('schemas');
$results = $this->fetchPragma('database_list');
foreach ($results as $row) {
$schemas[] = $row['name'];
}
$this->data['schemas'] = $schemas;
}
protected function loadTableNameData($schema)
{
if (isset($this->data['table_names'][$schema])) {
return;
}
$this->prepareDataHierarchy('table_names', $schema);
// FEATURE: Filename?
$p = $this->adapter->getPlatform();
$sql = 'SELECT "name", "type", "sql" FROM ' . $p->quoteIdentifierChain([$schema, 'sqlite_master'])
. ' WHERE "type" IN (\'table\',\'view\') AND "name" NOT LIKE \'sqlite_%\'';
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$tables = [];
foreach ($results->toArray() as $row) {
if ('table' == $row['type']) {
$table = [
'table_type' => 'BASE TABLE',
'view_definition' => null, // VIEW only
'check_option' => null, // VIEW only
'is_updatable' => null, // VIEW only
];
} else {
$table = [
'table_type' => 'VIEW',
'view_definition' => null,
'check_option' => 'NONE',
'is_updatable' => false,
];
// Parse out extra data
if (null !== ($data = $this->parseView($row['sql']))) {
$table = array_merge($table, $data);
}
}
$tables[$row['name']] = $table;
}
$this->data['table_names'][$schema] = $tables;
}
protected function loadColumnData($table, $schema)
{
if (isset($this->data['columns'][$schema][$table])) {
return;
}
$this->prepareDataHierarchy('columns', $schema, $table);
$this->prepareDataHierarchy('sqlite_columns', $schema, $table);
$results = $this->fetchPragma('table_info', $table, $schema);
$columns = [];
foreach ($results as $row) {
$columns[$row['name']] = [
// cid appears to be zero-based, ordinal position needs to be one-based
'ordinal_position' => $row['cid'] + 1,
'column_default' => $row['dflt_value'],
'is_nullable' => ! ($row['notnull']),
'data_type' => $row['type'],
'character_maximum_length' => null,
'character_octet_length' => null,
'numeric_precision' => null,
'numeric_scale' => null,
'numeric_unsigned' => null,
'erratas' => [],
];
// TODO: populate character_ and numeric_values with correct info
}
$this->data['columns'][$schema][$table] = $columns;
$this->data['sqlite_columns'][$schema][$table] = $results;
}
protected function loadConstraintData($table, $schema)
{
if (isset($this->data['constraints'][$schema][$table])) {
return;
}
$this->prepareDataHierarchy('constraints', $schema, $table);
$this->loadColumnData($table, $schema);
$primaryKey = [];
foreach ($this->data['sqlite_columns'][$schema][$table] as $col) {
if ($col['pk']) {
$primaryKey[] = $col['name'];
}
}
if (empty($primaryKey)) {
$primaryKey = null;
}
$constraints = [];
$indexes = $this->fetchPragma('index_list', $table, $schema);
foreach ($indexes as $index) {
if (! ($index['unique'])) {
continue;
}
$constraint = [
'constraint_name' => $index['name'],
'constraint_type' => 'UNIQUE',
'table_name' => $table,
'columns' => [],
];
$info = $this->fetchPragma('index_info', $index['name'], $schema);
foreach ($info as $column) {
$constraint['columns'][] = $column['name'];
}
if ($primaryKey === $constraint['columns']) {
$constraint['constraint_type'] = 'PRIMARY KEY';
$primaryKey = null;
}
$constraints[$constraint['constraint_name']] = $constraint;
}
if (null !== $primaryKey) {
$constraintName = '_zf_' . $table . '_PRIMARY';
$constraints[$constraintName] = [
'constraint_name' => $constraintName,
'constraint_type' => 'PRIMARY KEY',
'table_name' => $table,
'columns' => $primaryKey,
];
}
$foreignKeys = $this->fetchPragma('foreign_key_list', $table, $schema);
$id = $name = null;
foreach ($foreignKeys as $fk) {
if ($id !== $fk['id']) {
$id = $fk['id'];
$name = '_zf_' . $table . '_FOREIGN_KEY_' . ($id + 1);
$constraints[$name] = [
'constraint_name' => $name,
'constraint_type' => 'FOREIGN KEY',
'table_name' => $table,
'columns' => [],
'referenced_table_schema' => $schema,
'referenced_table_name' => $fk['table'],
'referenced_columns' => [],
// TODO: Verify match, on_update, and on_delete values conform to SQL Standard
'match_option' => strtoupper($fk['match']),
'update_rule' => strtoupper($fk['on_update']),
'delete_rule' => strtoupper($fk['on_delete']),
];
}
$constraints[$name]['columns'][] = $fk['from'];
$constraints[$name]['referenced_columns'][] = $fk['to'];
}
$this->data['constraints'][$schema][$table] = $constraints;
}
protected function loadTriggerData($schema)
{
if (isset($this->data['triggers'][$schema])) {
return;
}
$this->prepareDataHierarchy('triggers', $schema);
$p = $this->adapter->getPlatform();
$sql = 'SELECT "name", "tbl_name", "sql" FROM '
. $p->quoteIdentifierChain([$schema, 'sqlite_master'])
. ' WHERE "type" = \'trigger\'';
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
$triggers = [];
foreach ($results->toArray() as $row) {
$trigger = [
'trigger_name' => $row['name'],
'event_manipulation' => null, // in $row['sql']
'event_object_catalog' => null,
'event_object_schema' => $schema,
'event_object_table' => $row['tbl_name'],
'action_order' => 0,
'action_condition' => null, // in $row['sql']
'action_statement' => null, // in $row['sql']
'action_orientation' => 'ROW',
'action_timing' => null, // in $row['sql']
'action_reference_old_table' => null,
'action_reference_new_table' => null,
'action_reference_old_row' => 'OLD',
'action_reference_new_row' => 'NEW',
'created' => null,
];
// Parse out extra data
if (null !== ($data = $this->parseTrigger($row['sql']))) {
$trigger = array_merge($trigger, $data);
}
$triggers[$trigger['trigger_name']] = $trigger;
}
$this->data['triggers'][$schema] = $triggers;
}
protected function fetchPragma($name, $value = null, $schema = null)
{
$p = $this->adapter->getPlatform();
$sql = 'PRAGMA ';
if (null !== $schema) {
$sql .= $p->quoteIdentifier($schema) . '.';
}
$sql .= $name;
if (null !== $value) {
$sql .= '(' . $p->quoteTrustedValue($value) . ')';
}
$results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
if ($results instanceof ResultSetInterface) {
return $results->toArray();
}
return [];
}
protected function parseView($sql)
{
static $re = null;
if (null === $re) {
$identifierChain = $this->getIdentifierChainRegularExpression();
$re = $this->buildRegularExpression([
'CREATE',
['TEMP|TEMPORARY'],
'VIEW',
['IF', 'NOT', 'EXISTS'],
$identifierChain,
'AS',
'(?.+)',
[';'],
]);
}
if (! preg_match($re, $sql, $matches)) {
return;
}
return [
'view_definition' => $matches['view_definition'],
];
}
protected function parseTrigger($sql)
{
static $re = null;
if (null === $re) {
$identifier = $this->getIdentifierRegularExpression();
$identifierList = $this->getIdentifierListRegularExpression();
$identifierChain = $this->getIdentifierChainRegularExpression();
$re = $this->buildRegularExpression([
'CREATE',
['TEMP|TEMPORARY'],
'TRIGGER',
['IF', 'NOT', 'EXISTS'],
$identifierChain,
['(?BEFORE|AFTER|INSTEAD\\s+OF)', ],
'(?DELETE|INSERT|UPDATE)',
['OF', '(?' . $identifierList . ')'],
'ON',
'(?' . $identifier . ')',
['FOR', 'EACH', 'ROW'],
['WHEN', '(?.+)'],
'(?BEGIN',
'.+',
'END)',
[';'],
]);
}
if (! preg_match($re, $sql, $matches)) {
return;
}
$data = [];
foreach ($matches as $key => $value) {
if (is_string($key)) {
$data[$key] = $value;
}
}
// Normalize data and populate defaults, if necessary
$data['event_manipulation'] = strtoupper($data['event_manipulation']);
if (empty($data['action_condition'])) {
$data['action_condition'] = null;
}
if (! empty($data['action_timing'])) {
$data['action_timing'] = strtoupper($data['action_timing']);
if ('I' == $data['action_timing'][0]) {
// normalize the white-space between the two words
$data['action_timing'] = 'INSTEAD OF';
}
} else {
$data['action_timing'] = 'AFTER';
}
unset($data['column_usage']);
return $data;
}
protected function buildRegularExpression(array $re)
{
foreach ($re as &$value) {
if (is_array($value)) {
$value = '(?:' . implode('\\s*+', $value) . '\\s*+)?';
} else {
$value .= '\\s*+';
}
}
unset($value);
$re = '/^' . implode('\\s*+', $re) . '$/';
return $re;
}
protected function getIdentifierRegularExpression()
{
static $re = null;
if (null === $re) {
$re = '(?:' . implode('|', [
'"(?:[^"\\\\]++|\\\\.)*+"',
'`(?:[^`]++|``)*+`',
'\\[[^\\]]+\\]',
'[^\\s\\.]+',
]) . ')';
}
return $re;
}
protected function getIdentifierChainRegularExpression()
{
static $re = null;
if (null === $re) {
$identifier = $this->getIdentifierRegularExpression();
$re = $identifier . '(?:\\s*\\.\\s*' . $identifier . ')*+';
}
return $re;
}
protected function getIdentifierListRegularExpression()
{
static $re = null;
if (null === $re) {
$identifier = $this->getIdentifierRegularExpression();
$re = $identifier . '(?:\\s*,\\s*' . $identifier . ')*+';
}
return $re;
}
}
================================================
FILE: src/Zend/Db/src/Module.php
================================================
$provider->getDependencyConfig(),
];
}
}
================================================
FILE: src/Zend/Db/src/ResultSet/AbstractResultSet.php
================================================
buffer)) {
$this->buffer = [];
}
if ($dataSource instanceof ResultInterface) {
$this->fieldCount = $dataSource->getFieldCount();
$this->dataSource = $dataSource;
if ($dataSource->isBuffered()) {
$this->buffer = -1;
}
if (is_array($this->buffer)) {
$this->dataSource->rewind();
}
return $this;
}
if (is_array($dataSource)) {
// its safe to get numbers from an array
$first = current($dataSource);
reset($dataSource);
$this->fieldCount = $first === false ? 0 : count($first);
$this->dataSource = new ArrayIterator($dataSource);
$this->buffer = -1; // array's are a natural buffer
} elseif ($dataSource instanceof IteratorAggregate) {
$this->dataSource = $dataSource->getIterator();
} elseif ($dataSource instanceof Iterator) {
$this->dataSource = $dataSource;
} else {
throw new Exception\InvalidArgumentException(
'DataSource provided is not an array, nor does it implement Iterator or IteratorAggregate'
);
}
return $this;
}
/**
* @return self Provides a fluent interface
* @throws Exception\RuntimeException
*/
public function buffer()
{
if ($this->buffer === -2) {
throw new Exception\RuntimeException('Buffering must be enabled before iteration is started');
} elseif ($this->buffer === null) {
$this->buffer = [];
if ($this->dataSource instanceof ResultInterface) {
$this->dataSource->rewind();
}
}
return $this;
}
public function isBuffered()
{
if ($this->buffer === -1 || is_array($this->buffer)) {
return true;
}
return false;
}
/**
* Get the data source used to create the result set
*
* @return null|Iterator
*/
public function getDataSource()
{
return $this->dataSource;
}
/**
* Retrieve count of fields in individual rows of the result set
*
* @return int
*/
public function getFieldCount()
{
if (null !== $this->fieldCount) {
return $this->fieldCount;
}
$dataSource = $this->getDataSource();
if (null === $dataSource) {
return 0;
}
$dataSource->rewind();
if (! $dataSource->valid()) {
$this->fieldCount = 0;
return 0;
}
$row = $dataSource->current();
if (is_object($row) && $row instanceof Countable) {
$this->fieldCount = $row->count();
return $this->fieldCount;
}
$row = (array) $row;
$this->fieldCount = count($row);
return $this->fieldCount;
}
/**
* Iterator: move pointer to next item
*
* @return void
*/
#[ReturnTypeWillChange] public function next()
{
if ($this->buffer === null) {
$this->buffer = -2; // implicitly disable buffering from here on
}
if (! is_array($this->buffer) || $this->position == $this->dataSource->key()) {
$this->dataSource->next();
}
$this->position++;
}
/**
* Iterator: retrieve current key
*
* @return mixed
*/
#[ReturnTypeWillChange] public function key()
{
return $this->position;
}
/**
* Iterator: get current item
*
* @return array|null
*/
#[ReturnTypeWillChange] public function current()
{
if (-1 === $this->buffer) {
// datasource was an array when the resultset was initialized
return $this->dataSource->current();
}
if ($this->buffer === null) {
$this->buffer = -2; // implicitly disable buffering from here on
} elseif (is_array($this->buffer) && isset($this->buffer[$this->position])) {
return $this->buffer[$this->position];
}
$data = $this->dataSource->current();
if (is_array($this->buffer)) {
$this->buffer[$this->position] = $data;
}
return is_array($data) ? $data : null;
}
/**
* Iterator: is pointer valid?
*
* @return bool
*/
#[ReturnTypeWillChange] public function valid()
{
if (is_array($this->buffer) && isset($this->buffer[$this->position])) {
return true;
}
if ($this->dataSource instanceof Iterator) {
return $this->dataSource->valid();
} else {
$key = key($this->dataSource);
return ($key !== null);
}
}
/**
* Iterator: rewind
*
* @return void
*/
#[ReturnTypeWillChange] public function rewind()
{
if (! is_array($this->buffer)) {
if ($this->dataSource instanceof Iterator) {
$this->dataSource->rewind();
} else {
reset($this->dataSource);
}
}
$this->position = 0;
}
/**
* Countable: return count of rows
*
* @return int
*/
#[ReturnTypeWillChange] public function count()
{
if ($this->count !== null) {
return $this->count;
}
if ($this->dataSource instanceof Countable) {
$this->count = count($this->dataSource);
}
return $this->count;
}
/**
* Cast result set to array of arrays
*
* @return array
* @throws Exception\RuntimeException if any row is not castable to an array
*/
public function toArray()
{
$return = [];
foreach ($this as $row) {
if (is_array($row)) {
$return[] = $row;
} elseif (method_exists($row, 'toArray')) {
$return[] = $row->toArray();
} elseif (method_exists($row, 'getArrayCopy')) {
$return[] = $row->getArrayCopy();
} else {
throw new Exception\RuntimeException(
'Rows as part of this DataSource, with type ' . gettype($row) . ' cannot be cast to an array'
);
}
}
return $return;
}
}
================================================
FILE: src/Zend/Db/src/ResultSet/Exception/ExceptionInterface.php
================================================
setHydrator($hydrator ?: new $defaultHydratorClass());
$this->setObjectPrototype(($objectPrototype) ?: new ArrayObject);
}
/**
* Set the row object prototype
*
* @param object $objectPrototype
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function setObjectPrototype($objectPrototype)
{
if (! is_object($objectPrototype)) {
throw new Exception\InvalidArgumentException(
'An object must be set as the object prototype, a ' . gettype($objectPrototype) . ' was provided.'
);
}
$this->objectPrototype = $objectPrototype;
return $this;
}
/**
* Get the row object prototype
*
* @return object
*/
public function getObjectPrototype()
{
return $this->objectPrototype;
}
/**
* Set the hydrator to use for each row object
*
* @param HydratorInterface $hydrator
* @return self Provides a fluent interface
*/
public function setHydrator(HydratorInterface $hydrator)
{
$this->hydrator = $hydrator;
return $this;
}
/**
* Get the hydrator to use for each row object
*
* @return HydratorInterface
*/
public function getHydrator()
{
return $this->hydrator;
}
/**
* Iterator: get current item
*
* @return object
*/
#[ReturnTypeWillChange]
public function current()
{
if ($this->buffer === null) {
$this->buffer = -2; // implicitly disable buffering from here on
} elseif (is_array($this->buffer) && isset($this->buffer[$this->position])) {
return $this->buffer[$this->position];
}
$data = $this->dataSource->current();
$object = is_array($data) ? $this->hydrator->hydrate($data, clone $this->objectPrototype) : false;
if (is_array($this->buffer)) {
$this->buffer[$this->position] = $object;
}
return $object;
}
/**
* Cast result set to array of arrays
*
* @return array
* @throws Exception\RuntimeException if any row is not castable to an array
*/
public function toArray()
{
$return = [];
foreach ($this as $row) {
$return[] = $this->hydrator->extract($row);
}
return $return;
}
}
================================================
FILE: src/Zend/Db/src/ResultSet/ResultSet.php
================================================
allowedReturnTypes, true)) {
$this->returnType = $returnType;
} else {
$this->returnType = self::TYPE_ARRAYOBJECT;
}
if ($this->returnType === self::TYPE_ARRAYOBJECT) {
$this->setArrayObjectPrototype(($arrayObjectPrototype) ?: new ArrayObject([], ArrayObject::ARRAY_AS_PROPS));
}
}
/**
* Set the row object prototype
*
* @param ArrayObject $arrayObjectPrototype
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function setArrayObjectPrototype($arrayObjectPrototype)
{
if (! is_object($arrayObjectPrototype)
|| (
! $arrayObjectPrototype instanceof ArrayObject
&& ! method_exists($arrayObjectPrototype, 'exchangeArray')
)
) {
throw new Exception\InvalidArgumentException(
'Object must be of type ArrayObject, or at least implement exchangeArray'
);
}
$this->arrayObjectPrototype = $arrayObjectPrototype;
return $this;
}
/**
* Get the row object prototype
*
* @return ArrayObject
*/
public function getArrayObjectPrototype()
{
return $this->arrayObjectPrototype;
}
/**
* Get the return type to use when returning objects from the set
*
* @return string
*/
public function getReturnType()
{
return $this->returnType;
}
/**
* @return array|\ArrayObject|null
*/
#[ReturnTypeWillChange]
public function current()
{
$data = parent::current();
if ($this->returnType === self::TYPE_ARRAYOBJECT && is_array($data)) {
/** @var $ao ArrayObject */
$ao = clone $this->arrayObjectPrototype;
if ($ao instanceof ArrayObject || method_exists($ao, 'exchangeArray')) {
$ao->exchangeArray($data);
}
return $ao;
}
return $data;
}
}
================================================
FILE: src/Zend/Db/src/ResultSet/ResultSetInterface.php
================================================
isInitialized) {
return;
}
if (! $this->featureSet instanceof Feature\FeatureSet) {
$this->featureSet = new Feature\FeatureSet;
}
$this->featureSet->setRowGateway($this);
$this->featureSet->apply('preInitialize', []);
if (! is_string($this->table) && ! $this->table instanceof TableIdentifier) {
throw new Exception\RuntimeException('This row object does not have a valid table set.');
}
if ($this->primaryKeyColumn === null) {
throw new Exception\RuntimeException('This row object does not have a primary key column set.');
} elseif (is_string($this->primaryKeyColumn)) {
$this->primaryKeyColumn = (array) $this->primaryKeyColumn;
}
if (! $this->sql instanceof Sql) {
throw new Exception\RuntimeException('This row object does not have a Sql object set.');
}
$this->featureSet->apply('postInitialize', []);
$this->isInitialized = true;
}
/**
* Populate Data
*
* @param array $rowData
* @param bool $rowExistsInDatabase
* @return self Provides a fluent interface
*/
public function populate(array $rowData, $rowExistsInDatabase = false)
{
$this->initialize();
$this->data = $rowData;
if ($rowExistsInDatabase) {
$this->processPrimaryKeyData();
} else {
$this->primaryKeyData = null;
}
return $this;
}
/**
* @param mixed $array
* @return AbstractRowGateway
*/
public function exchangeArray($array)
{
return $this->populate($array, true);
}
/**
* Save
*
* @return int
*/
public function save()
{
$this->initialize();
if ($this->rowExistsInDatabase()) {
// UPDATE
$data = $this->data;
$where = [];
$isPkModified = false;
// primary key is always an array even if its a single column
foreach ($this->primaryKeyColumn as $pkColumn) {
$where[$pkColumn] = $this->primaryKeyData[$pkColumn];
if ($data[$pkColumn] == $this->primaryKeyData[$pkColumn]) {
unset($data[$pkColumn]);
} else {
$isPkModified = true;
}
}
$statement = $this->sql->prepareStatementForSqlObject($this->sql->update()->set($data)->where($where));
$result = $statement->execute();
$rowsAffected = $result->getAffectedRows();
unset($statement, $result); // cleanup
// If one or more primary keys are modified, we update the where clause
if ($isPkModified) {
foreach ($this->primaryKeyColumn as $pkColumn) {
if ($data[$pkColumn] != $this->primaryKeyData[$pkColumn]) {
$where[$pkColumn] = $data[$pkColumn];
}
}
}
} else {
// INSERT
$insert = $this->sql->insert();
$insert->values($this->data);
$statement = $this->sql->prepareStatementForSqlObject($insert);
$result = $statement->execute();
if (($primaryKeyValue = $result->getGeneratedValue()) && count($this->primaryKeyColumn) == 1) {
$this->primaryKeyData = [$this->primaryKeyColumn[0] => $primaryKeyValue];
} else {
// make primary key data available so that $where can be complete
$this->processPrimaryKeyData();
}
$rowsAffected = $result->getAffectedRows();
unset($statement, $result); // cleanup
$where = [];
// primary key is always an array even if its a single column
foreach ($this->primaryKeyColumn as $pkColumn) {
$where[$pkColumn] = $this->primaryKeyData[$pkColumn];
}
}
// refresh data
$statement = $this->sql->prepareStatementForSqlObject($this->sql->select()->where($where));
$result = $statement->execute();
$rowData = $result->current();
unset($statement, $result); // cleanup
// make sure data and original data are in sync after save
$this->populate($rowData, true);
// return rows affected
return $rowsAffected;
}
/**
* Delete
*
* @return int
*/
public function delete()
{
$this->initialize();
$where = [];
// primary key is always an array even if its a single column
foreach ($this->primaryKeyColumn as $pkColumn) {
$where[$pkColumn] = $this->primaryKeyData[$pkColumn] ?? null;
}
// @todo determine if we need to do a select to ensure 1 row will be affected
$statement = $this->sql->prepareStatementForSqlObject($this->sql->delete()->where($where));
$result = $statement->execute();
$affectedRows = $result->getAffectedRows();
if ($affectedRows == 1) {
// detach from database
$this->primaryKeyData = null;
}
return $affectedRows;
}
/**
* Offset Exists
*
* @param string $offset
* @return bool
*/
#[ReturnTypeWillChange] public function offsetExists($offset)
{
return array_key_exists($offset, $this->data);
}
/**
* Offset get
*
* @param string $offset
* @return mixed
*/
#[ReturnTypeWillChange] public function offsetGet($offset)
{
return $this->data[$offset];
}
/**
* Offset set
*
* @param string $offset
* @param mixed $value
* @return self Provides a fluent interface
*/
#[ReturnTypeWillChange] public function offsetSet($offset, $value)
{
$this->data[$offset] = $value;
return $this;
}
/**
* Offset unset
*
* @param string $offset
* @return self Provides a fluent interface
*/
#[ReturnTypeWillChange] public function offsetUnset($offset)
{
$this->data[$offset] = null;
return $this;
}
/**
* @return int
*/
#[ReturnTypeWillChange] public function count()
{
return count($this->data);
}
/**
* To array
*
* @return array
*/
public function toArray()
{
return $this->data;
}
/**
* __get
*
* @param string $name
* @throws Exception\InvalidArgumentException
* @return mixed
*/
public function __get($name)
{
if (array_key_exists($name, $this->data)) {
return $this->data[$name];
} else {
throw new Exception\InvalidArgumentException('Not a valid column in this row: ' . $name);
}
}
/**
* __set
*
* @param string $name
* @param mixed $value
* @return void
*/
public function __set($name, $value)
{
$this->offsetSet($name, $value);
}
/**
* __isset
*
* @param string $name
* @return bool
*/
public function __isset($name)
{
return $this->offsetExists($name);
}
/**
* __unset
*
* @param string $name
* @return void
*/
public function __unset($name)
{
$this->offsetUnset($name);
}
/**
* @return bool
*/
public function rowExistsInDatabase()
{
return ($this->primaryKeyData !== null);
}
/**
* @throws Exception\RuntimeException
*/
protected function processPrimaryKeyData()
{
$this->primaryKeyData = [];
foreach ($this->primaryKeyColumn as $column) {
if (! isset($this->data[$column])) {
throw new Exception\RuntimeException(
'While processing primary key data, a known key ' . $column . ' was not found in the data array'
);
}
$this->primaryKeyData[$column] = $this->data[$column];
}
}
}
================================================
FILE: src/Zend/Db/src/RowGateway/Exception/ExceptionInterface.php
================================================
rowGateway = $rowGateway;
}
/**
* @throws \Zend\Db\RowGateway\Exception\RuntimeException
*/
public function initialize()
{
throw new Exception\RuntimeException('This method is not intended to be called on this object.');
}
/**
* @return array
*/
public function getMagicMethodSpecifications()
{
return [];
}
}
================================================
FILE: src/Zend/Db/src/RowGateway/Feature/FeatureSet.php
================================================
addFeatures($features);
}
}
/**
* @param AbstractRowGateway $rowGateway
* @return self Provides a fluent interface
*/
public function setRowGateway(AbstractRowGateway $rowGateway)
{
$this->rowGateway = $rowGateway;
foreach ($this->features as $feature) {
$feature->setRowGateway($this->rowGateway);
}
return $this;
}
public function getFeatureByClassName($featureClassName)
{
$feature = false;
foreach ($this->features as $potentialFeature) {
if ($potentialFeature instanceof $featureClassName) {
$feature = $potentialFeature;
break;
}
}
return $feature;
}
/**
* @param array $features
* @return self Provides a fluent interface
*/
public function addFeatures(array $features)
{
foreach ($features as $feature) {
$this->addFeature($feature);
}
return $this;
}
/**
* @param AbstractFeature $feature
* @return self Provides a fluent interface
*/
public function addFeature(AbstractFeature $feature)
{
$this->features[] = $feature;
$feature->setRowGateway($feature);
return $this;
}
public function apply($method, $args)
{
foreach ($this->features as $feature) {
if (method_exists($feature, $method)) {
$return = call_user_func_array([$feature, $method], $args);
if ($return === self::APPLY_HALT) {
break;
}
}
}
}
/**
* @return bool
*/
public function canCallMagicGet()
{
return false;
}
/**
* @return mixed
*/
public function callMagicGet()
{
$return = null;
return $return;
}
/**
* @return bool
*/
public function canCallMagicSet()
{
return false;
}
/**
* @return mixed
*/
public function callMagicSet()
{
$return = null;
return $return;
}
/**
* @return bool
*/
public function canCallMagicCall()
{
return false;
}
/**
* @return mixed
*/
public function callMagicCall()
{
$return = null;
return $return;
}
}
================================================
FILE: src/Zend/Db/src/RowGateway/RowGateway.php
================================================
primaryKeyColumn = empty($primaryKeyColumn) ? null : (array) $primaryKeyColumn;
// set table
$this->table = $table;
// set Sql object
if ($adapterOrSql instanceof Sql) {
$this->sql = $adapterOrSql;
} elseif ($adapterOrSql instanceof AdapterInterface) {
$this->sql = new Sql($adapterOrSql, $this->table);
} else {
throw new Exception\InvalidArgumentException('A valid Sql object was not provided.');
}
if ($this->sql->getTable() !== $this->table) {
throw new Exception\InvalidArgumentException(
'The Sql object provided does not have a table that matches this row object'
);
}
$this->initialize();
}
}
================================================
FILE: src/Zend/Db/src/RowGateway/RowGatewayInterface.php
================================================
buildNormalizedArgument($argument, self::TYPE_VALUE);
}
if (is_scalar($argument) || $argument === null) {
return $this->buildNormalizedArgument($argument, $defaultType);
}
if (is_array($argument)) {
$value = current($argument);
if ($value instanceof ExpressionInterface || $value instanceof SqlInterface) {
return $this->buildNormalizedArgument($value, self::TYPE_VALUE);
}
$key = key($argument);
if (is_integer($key) && ! in_array($value, $this->allowedTypes)) {
return $this->buildNormalizedArgument($value, $defaultType);
}
return $this->buildNormalizedArgument($key, $value);
}
throw new Exception\InvalidArgumentException(sprintf(
'$argument should be %s or %s or %s or %s or %s, "%s" given',
'null',
'scalar',
'array',
'Zend\Db\Sql\ExpressionInterface',
'Zend\Db\Sql\SqlInterface',
is_object($argument) ? get_class($argument) : gettype($argument)
));
}
/**
* @param mixed $argument
* @param string $argumentType
*
* @return array
*
* @throws Exception\InvalidArgumentException
*/
private function buildNormalizedArgument($argument, $argumentType)
{
if (! in_array($argumentType, $this->allowedTypes)) {
throw new Exception\InvalidArgumentException(sprintf(
'Argument type should be in array(%s)',
implode(',', $this->allowedTypes)
));
}
return [
$argument,
$argumentType,
];
}
}
================================================
FILE: src/Zend/Db/src/Sql/AbstractPreparableSql.php
================================================
getParameterContainer();
if (! $parameterContainer instanceof ParameterContainer) {
$parameterContainer = new ParameterContainer();
$statementContainer->setParameterContainer($parameterContainer);
}
$statementContainer->setSql(
$this->buildSqlString($adapter->getPlatform(), $adapter->getDriver(), $parameterContainer)
);
return $statementContainer;
}
}
================================================
FILE: src/Zend/Db/src/Sql/AbstractSql.php
================================================
'', 'subselectCount' => 0];
/**
* @var array
*/
protected $instanceParameterIndex = [];
/**
* {@inheritDoc}
*/
public function getSqlString(?PlatformInterface $adapterPlatform = null)
{
$adapterPlatform = ($adapterPlatform) ?: new DefaultAdapterPlatform;
return $this->buildSqlString($adapterPlatform);
}
/**
* @param PlatformInterface $platform
* @param DriverInterface|null $driver
* @param ParameterContainer|null $parameterContainer
* @return string
*/
protected function buildSqlString(
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
$this->localizeVariables();
$sqls = [];
$parameters = [];
foreach ($this->specifications as $name => $specification) {
$parameters[$name] = $this->{'process' . $name}(
$platform,
$driver,
$parameterContainer,
$sqls,
$parameters
);
if ($specification && is_array($parameters[$name])) {
$sqls[$name] = $this->createSqlFromSpecificationAndParameters($specification, $parameters[$name]);
continue;
}
if (is_string($parameters[$name])) {
$sqls[$name] = $parameters[$name];
}
}
return rtrim(implode(' ', $sqls), "\n ,");
}
/**
* Render table with alias in from/join parts
*
* @todo move TableIdentifier concatenation here
* @param string $table
* @param string $alias
* @return string
*/
protected function renderTable($table, $alias = null)
{
return $table . ($alias ? ' AS ' . $alias : '');
}
/**
* @staticvar int $runtimeExpressionPrefix
* @param ExpressionInterface $expression
* @param PlatformInterface $platform
* @param DriverInterface|null $driver
* @param ParameterContainer|null $parameterContainer
* @param null|string $namedParameterPrefix
* @return string
* @throws Exception\RuntimeException
*/
protected function processExpression(
ExpressionInterface $expression,
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null,
$namedParameterPrefix = null
) {
$namedParameterPrefix = ! $namedParameterPrefix
? $namedParameterPrefix
: $this->processInfo['paramPrefix'] . $namedParameterPrefix;
// static counter for the number of times this method was invoked across the PHP runtime
static $runtimeExpressionPrefix = 0;
if ($parameterContainer && ((! is_string($namedParameterPrefix) || $namedParameterPrefix == ''))) {
$namedParameterPrefix = sprintf('expr%04dParam', ++$runtimeExpressionPrefix);
} else {
$namedParameterPrefix = preg_replace('/\s/', '__', $namedParameterPrefix);
}
$sql = '';
// initialize variables
$parts = $expression->getExpressionData();
if (! isset($this->instanceParameterIndex[$namedParameterPrefix])) {
$this->instanceParameterIndex[$namedParameterPrefix] = 1;
}
$expressionParamIndex = &$this->instanceParameterIndex[$namedParameterPrefix];
foreach ($parts as $part) {
// #7407: use $expression->getExpression() to get the unescaped
// version of the expression
if (is_string($part) && $expression instanceof Expression) {
$sql .= $expression->getExpression();
continue;
}
// If it is a string, simply tack it onto the return sql
// "specification" string
if (is_string($part)) {
$sql .= $part;
continue;
}
if (! is_array($part)) {
throw new Exception\RuntimeException(
'Elements returned from getExpressionData() array must be a string or array.'
);
}
// Process values and types (the middle and last position of the
// expression data)
$values = $part[1];
$types = $part[2] ?? [];
foreach ($values as $vIndex => $value) {
if (! isset($types[$vIndex])) {
continue;
}
$type = $types[$vIndex];
if ($value instanceof Select) {
// process sub-select
$values[$vIndex] = '('
. $this->processSubSelect($value, $platform, $driver, $parameterContainer)
. ')';
} elseif ($value instanceof ExpressionInterface) {
// recursive call to satisfy nested expressions
$values[$vIndex] = $this->processExpression(
$value,
$platform,
$driver,
$parameterContainer,
$namedParameterPrefix . $vIndex . 'subpart'
);
} elseif ($type == ExpressionInterface::TYPE_IDENTIFIER) {
$values[$vIndex] = $platform->quoteIdentifierInFragment($value);
} elseif ($type == ExpressionInterface::TYPE_VALUE) {
// if prepareType is set, it means that this particular value must be
// passed back to the statement in a way it can be used as a placeholder value
if ($parameterContainer) {
$name = $namedParameterPrefix . $expressionParamIndex++;
$parameterContainer->offsetSet($name, $value);
$values[$vIndex] = $driver->formatParameterName($name);
continue;
}
// if not a preparable statement, simply quote the value and move on
$values[$vIndex] = $platform->quoteValue($value);
} elseif ($type == ExpressionInterface::TYPE_LITERAL) {
$values[$vIndex] = $value;
}
}
// After looping the values, interpolate them into the sql string
// (they might be placeholder names, or values)
$sql .= vsprintf($part[0], $values);
}
return $sql;
}
/**
* @param string|array $specifications
* @param array $parameters
*
* @return string
*
* @throws Exception\RuntimeException
*/
protected function createSqlFromSpecificationAndParameters($specifications, $parameters)
{
if (is_string($specifications)) {
return vsprintf($specifications, $parameters);
}
$parametersCount = count($parameters);
foreach ($specifications as $specificationString => $paramSpecs) {
if ($parametersCount == count($paramSpecs)) {
break;
}
unset($specificationString, $paramSpecs);
}
if (! isset($specificationString)) {
throw new Exception\RuntimeException(
'A number of parameters was found that is not supported by this specification'
);
}
$topParameters = [];
foreach ($parameters as $position => $paramsForPosition) {
if (isset($paramSpecs[$position]['combinedby'])) {
$multiParamValues = [];
foreach ($paramsForPosition as $multiParamsForPosition) {
if (is_array($multiParamsForPosition)) {
$ppCount = count($multiParamsForPosition);
} else {
$ppCount = 1;
}
if (! isset($paramSpecs[$position][$ppCount])) {
throw new Exception\RuntimeException(sprintf(
'A number of parameters (%d) was found that is not supported by this specification',
$ppCount
));
}
$multiParamValues[] = vsprintf($paramSpecs[$position][$ppCount], $multiParamsForPosition);
}
$topParameters[] = implode($paramSpecs[$position]['combinedby'], $multiParamValues);
} elseif ($paramSpecs[$position] !== null) {
$ppCount = count($paramsForPosition);
if (! isset($paramSpecs[$position][$ppCount])) {
throw new Exception\RuntimeException(sprintf(
'A number of parameters (%d) was found that is not supported by this specification',
$ppCount
));
}
$topParameters[] = vsprintf($paramSpecs[$position][$ppCount], $paramsForPosition);
} else {
$topParameters[] = $paramsForPosition;
}
}
return vsprintf($specificationString, $topParameters);
}
/**
* @param Select $subselect
* @param PlatformInterface $platform
* @param DriverInterface|null $driver
* @param ParameterContainer|null $parameterContainer
* @return string
*/
protected function processSubSelect(
Select $subselect,
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
if ($this instanceof PlatformDecoratorInterface) {
$decorator = clone $this;
$decorator->setSubject($subselect);
} else {
$decorator = $subselect;
}
if ($parameterContainer) {
// Track subselect prefix and count for parameters
$processInfoContext = ($decorator instanceof PlatformDecoratorInterface) ? $subselect : $decorator;
$this->processInfo['subselectCount']++;
$processInfoContext->processInfo['subselectCount'] = $this->processInfo['subselectCount'];
$processInfoContext->processInfo['paramPrefix'] = 'subselect'
. $processInfoContext->processInfo['subselectCount'];
$sql = $decorator->buildSqlString($platform, $driver, $parameterContainer);
// copy count
$this->processInfo['subselectCount'] = $decorator->processInfo['subselectCount'];
return $sql;
}
return $decorator->buildSqlString($platform, $driver, $parameterContainer);
}
/**
* @param Join[] $joins
* @param PlatformInterface $platform
* @param DriverInterface|null $driver
* @param ParameterContainer|null $parameterContainer
* @return null|string[] Null if no joins present, array of JOIN statements
* otherwise
* @throws Exception\InvalidArgumentException for invalid JOIN table names.
*/
protected function processJoin(
Join $joins,
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
if (! $joins->count()) {
return;
}
// process joins
$joinSpecArgArray = [];
foreach ($joins->getJoins() as $j => $join) {
$joinName = null;
$joinAs = null;
// table name
if (is_array($join['name'])) {
$joinName = current($join['name']);
$joinAs = $platform->quoteIdentifier(key($join['name']));
} else {
$joinName = $join['name'];
}
if ($joinName instanceof Expression) {
$joinName = $joinName->getExpression();
} elseif ($joinName instanceof TableIdentifier) {
$joinName = $joinName->getTableAndSchema();
$joinName = ($joinName[1]
? $platform->quoteIdentifier($joinName[1]) . $platform->getIdentifierSeparator()
: '') . $platform->quoteIdentifier($joinName[0]);
} elseif ($joinName instanceof Select) {
$joinName = '(' . $this->processSubSelect($joinName, $platform, $driver, $parameterContainer) . ')';
} elseif (is_string($joinName) || (is_object($joinName) && is_callable([$joinName, '__toString']))) {
$joinName = $platform->quoteIdentifier($joinName);
} else {
throw new Exception\InvalidArgumentException(sprintf(
'Join name expected to be Expression|TableIdentifier|Select|string, "%s" given',
gettype($joinName)
));
}
$joinSpecArgArray[$j] = [
strtoupper($join['type']),
$this->renderTable($joinName, $joinAs),
];
// on expression
// note: for Expression objects, pass them to processExpression with a prefix specific to each join
// (used for named parameters)
if (($join['on'] instanceof ExpressionInterface)) {
$joinSpecArgArray[$j][] = $this->processExpression(
$join['on'],
$platform,
$driver,
$parameterContainer,
'join' . ($j + 1) . 'part'
);
} else {
// on
$joinSpecArgArray[$j][] = $platform->quoteIdentifierInFragment(
$join['on'],
['=', 'AND', 'OR', '(', ')', 'BETWEEN', '<', '>']
);
}
}
return [$joinSpecArgArray];
}
/**
* @param null|array|ExpressionInterface|Select $column
* @param PlatformInterface $platform
* @param DriverInterface|null $driver
* @param null|string $namedParameterPrefix
* @param ParameterContainer|null $parameterContainer
* @return string
*/
protected function resolveColumnValue(
$column,
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null,
$namedParameterPrefix = null
) {
$namedParameterPrefix = ! $namedParameterPrefix
? $namedParameterPrefix
: $this->processInfo['paramPrefix'] . $namedParameterPrefix;
$isIdentifier = false;
$fromTable = '';
if (is_array($column)) {
if (isset($column['isIdentifier'])) {
$isIdentifier = (bool) $column['isIdentifier'];
}
if (isset($column['fromTable']) && $column['fromTable'] !== null) {
$fromTable = $column['fromTable'];
}
$column = $column['column'];
}
if ($column instanceof ExpressionInterface) {
return $this->processExpression($column, $platform, $driver, $parameterContainer, $namedParameterPrefix);
}
if ($column instanceof Select) {
return '(' . $this->processSubSelect($column, $platform, $driver, $parameterContainer) . ')';
}
if ($column === null) {
return 'NULL';
}
return $isIdentifier
? $fromTable . $platform->quoteIdentifierInFragment($column)
: $platform->quoteValue($column);
}
/**
* @param string|TableIdentifier|Select $table
* @param PlatformInterface $platform
* @param DriverInterface|null $driver
* @param ParameterContainer|null $parameterContainer
* @return string
*/
protected function resolveTable(
$table,
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
$schema = null;
if ($table instanceof TableIdentifier) {
[$table, $schema] = $table->getTableAndSchema();
}
if ($table instanceof Select) {
$table = '(' . $this->processSubselect($table, $platform, $driver, $parameterContainer) . ')';
} elseif ($table) {
$table = $platform->quoteIdentifier($table);
}
if ($schema && $table) {
$table = $platform->quoteIdentifier($schema) . $platform->getIdentifierSeparator() . $table;
}
return $table;
}
/**
* Copy variables from the subject into the local properties
*/
protected function localizeVariables()
{
if (! $this instanceof PlatformDecoratorInterface) {
return;
}
foreach (get_object_vars($this->subject) as $name => $value) {
$this->{$name} = $value;
}
}
}
================================================
FILE: src/Zend/Db/src/Sql/Combine.php
================================================
'%1$s (%2$s) ',
];
/**
* @var Select[][]
*/
private $combine = [];
/**
* @param Select|array|null $select
* @param string $type
* @param string $modifier
*/
public function __construct($select = null, $type = self::COMBINE_UNION, $modifier = '')
{
if ($select) {
$this->combine($select, $type, $modifier);
}
}
/**
* Create combine clause
*
* @param Select|array $select
* @param string $type
* @param string $modifier
*
* @return self Provides a fluent interface
*
* @throws Exception\InvalidArgumentException
*/
public function combine($select, $type = self::COMBINE_UNION, $modifier = '')
{
if (is_array($select)) {
foreach ($select as $combine) {
if ($combine instanceof Select) {
$combine = [$combine];
}
$this->combine(
$combine[0],
$combine[1] ?? $type,
$combine[2] ?? $modifier
);
}
return $this;
}
if (! $select instanceof Select) {
throw new Exception\InvalidArgumentException(sprintf(
'$select must be a array or instance of Select, "%s" given',
is_object($select) ? get_class($select) : gettype($select)
));
}
$this->combine[] = [
'select' => $select,
'type' => $type,
'modifier' => $modifier
];
return $this;
}
/**
* Create union clause
*
* @param Select|array $select
* @param string $modifier
*
* @return self
*/
public function union($select, $modifier = '')
{
return $this->combine($select, self::COMBINE_UNION, $modifier);
}
/**
* Create except clause
*
* @param Select|array $select
* @param string $modifier
*
* @return self
*/
public function except($select, $modifier = '')
{
return $this->combine($select, self::COMBINE_EXCEPT, $modifier);
}
/**
* Create intersect clause
*
* @param Select|array $select
* @param string $modifier
* @return self
*/
public function intersect($select, $modifier = '')
{
return $this->combine($select, self::COMBINE_INTERSECT, $modifier);
}
/**
* Build sql string
*
* @param PlatformInterface $platform
* @param DriverInterface|null $driver
* @param ParameterContainer|null $parameterContainer
*
* @return string
*/
protected function buildSqlString(
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
if (! $this->combine) {
return;
}
$sql = '';
foreach ($this->combine as $i => $combine) {
$type = $i == 0
? ''
: strtoupper($combine['type'] . ($combine['modifier'] ? ' ' . $combine['modifier'] : ''));
$select = $this->processSubSelect($combine['select'], $platform, $driver, $parameterContainer);
$sql .= sprintf(
$this->specifications[self::COMBINE],
$type,
$select
);
}
return trim($sql, ' ');
}
/**
* @return self Provides a fluent interface
*/
public function alignColumns()
{
if (! $this->combine) {
return $this;
}
$allColumns = [];
foreach ($this->combine as $combine) {
$allColumns = array_merge(
$allColumns,
$combine['select']->getRawState(self::COLUMNS)
);
}
foreach ($this->combine as $combine) {
$combineColumns = $combine['select']->getRawState(self::COLUMNS);
$aligned = [];
foreach ($allColumns as $alias => $column) {
$aligned[$alias] = $combineColumns[$alias] ?? new Predicate\Expression('NULL');
}
$combine['select']->columns($aligned, false);
}
return $this;
}
/**
* Get raw state
*
* @param string $key
*
* @return array
*/
public function getRawState($key = null)
{
$rawState = [
self::COMBINE => $this->combine,
self::COLUMNS => $this->combine
? $this->combine[0]['select']->getRawState(self::COLUMNS)
: [],
];
return (isset($key) && array_key_exists($key, $rawState)) ? $rawState[$key] : $rawState;
}
}
================================================
FILE: src/Zend/Db/src/Sql/Ddl/AlterTable.php
================================================
"ALTER TABLE %1\$s\n",
self::ADD_COLUMNS => [
"%1\$s" => [
[1 => "ADD COLUMN %1\$s,\n", 'combinedby' => ""]
]
],
self::CHANGE_COLUMNS => [
"%1\$s" => [
[2 => "CHANGE COLUMN %1\$s %2\$s,\n", 'combinedby' => ""],
]
],
self::DROP_COLUMNS => [
"%1\$s" => [
[1 => "DROP COLUMN %1\$s,\n", 'combinedby' => ""],
]
],
self::ADD_CONSTRAINTS => [
"%1\$s" => [
[1 => "ADD %1\$s,\n", 'combinedby' => ""],
]
],
self::DROP_CONSTRAINTS => [
"%1\$s" => [
[1 => "DROP CONSTRAINT %1\$s,\n", 'combinedby' => ""],
]
]
];
/**
* @var string
*/
protected $table = '';
/**
* @param string|TableIdentifier $table
*/
public function __construct($table = '')
{
($table) ? $this->setTable($table) : null;
}
/**
* @param string $name
* @return self Provides a fluent interface
*/
public function setTable($name)
{
$this->table = $name;
return $this;
}
/**
* @param Column\ColumnInterface $column
* @return self Provides a fluent interface
*/
public function addColumn(Column\ColumnInterface $column)
{
$this->addColumns[] = $column;
return $this;
}
/**
* @param string $name
* @param Column\ColumnInterface $column
* @return self Provides a fluent interface
*/
public function changeColumn($name, Column\ColumnInterface $column)
{
$this->changeColumns[$name] = $column;
return $this;
}
/**
* @param string $name
* @return self Provides a fluent interface
*/
public function dropColumn($name)
{
$this->dropColumns[] = $name;
return $this;
}
/**
* @param string $name
* @return self Provides a fluent interface
*/
public function dropConstraint($name)
{
$this->dropConstraints[] = $name;
return $this;
}
/**
* @param Constraint\ConstraintInterface $constraint
* @return self Provides a fluent interface
*/
public function addConstraint(Constraint\ConstraintInterface $constraint)
{
$this->addConstraints[] = $constraint;
return $this;
}
/**
* @param string|null $key
* @return array
*/
public function getRawState($key = null)
{
$rawState = [
self::TABLE => $this->table,
self::ADD_COLUMNS => $this->addColumns,
self::DROP_COLUMNS => $this->dropColumns,
self::CHANGE_COLUMNS => $this->changeColumns,
self::ADD_CONSTRAINTS => $this->addConstraints,
self::DROP_CONSTRAINTS => $this->dropConstraints,
];
return (isset($key) && array_key_exists($key, $rawState)) ? $rawState[$key] : $rawState;
}
protected function processTable(?PlatformInterface $adapterPlatform = null)
{
return [$this->resolveTable($this->table, $adapterPlatform)];
}
protected function processAddColumns(?PlatformInterface $adapterPlatform = null)
{
$sqls = [];
foreach ($this->addColumns as $column) {
$sqls[] = $this->processExpression($column, $adapterPlatform);
}
return [$sqls];
}
protected function processChangeColumns(?PlatformInterface $adapterPlatform = null)
{
$sqls = [];
foreach ($this->changeColumns as $name => $column) {
$sqls[] = [
$adapterPlatform->quoteIdentifier($name),
$this->processExpression($column, $adapterPlatform)
];
}
return [$sqls];
}
protected function processDropColumns(?PlatformInterface $adapterPlatform = null)
{
$sqls = [];
foreach ($this->dropColumns as $column) {
$sqls[] = $adapterPlatform->quoteIdentifier($column);
}
return [$sqls];
}
protected function processAddConstraints(?PlatformInterface $adapterPlatform = null)
{
$sqls = [];
foreach ($this->addConstraints as $constraint) {
$sqls[] = $this->processExpression($constraint, $adapterPlatform);
}
return [$sqls];
}
protected function processDropConstraints(?PlatformInterface $adapterPlatform = null)
{
$sqls = [];
foreach ($this->dropConstraints as $constraint) {
$sqls[] = $adapterPlatform->quoteIdentifier($constraint);
}
return [$sqls];
}
}
================================================
FILE: src/Zend/Db/src/Sql/Ddl/Column/AbstractLengthColumn.php
================================================
setLength($length);
parent::__construct($name, $nullable, $default, $options);
}
/**
* @param int $length
* @return self Provides a fluent interface
*/
public function setLength($length)
{
$this->length = (int) $length;
return $this;
}
/**
* @return int
*/
public function getLength()
{
return $this->length;
}
/**
* @return string
*/
protected function getLengthExpression()
{
return (string) $this->length;
}
/**
* @return array
*/
public function getExpressionData()
{
$data = parent::getExpressionData();
if ($this->getLengthExpression()) {
$data[0][1][1] .= '(' . $this->getLengthExpression() . ')';
}
return $data;
}
}
================================================
FILE: src/Zend/Db/src/Sql/Ddl/Column/AbstractPrecisionColumn.php
================================================
setDecimal($decimal);
parent::__construct($name, $digits, $nullable, $default, $options);
}
/**
* @param int $digits
*
* @return self
*/
public function setDigits($digits)
{
return $this->setLength($digits);
}
/**
* @return int
*/
public function getDigits()
{
return $this->getLength();
}
/**
* @param int|null $decimal
* @return self Provides a fluent interface
*/
public function setDecimal($decimal)
{
$this->decimal = null === $decimal ? null : (int) $decimal;
return $this;
}
/**
* @return int|null
*/
public function getDecimal()
{
return $this->decimal;
}
/**
* {@inheritDoc}
*/
protected function getLengthExpression()
{
if ($this->decimal !== null) {
return $this->length . ',' . $this->decimal;
}
return $this->length;
}
}
================================================
FILE: src/Zend/Db/src/Sql/Ddl/Column/AbstractTimestampColumn.php
================================================
specification;
$params = [];
$params[] = $this->name;
$params[] = $this->type;
$types = [self::TYPE_IDENTIFIER, self::TYPE_LITERAL];
if (! $this->isNullable) {
$spec .= ' NOT NULL';
}
if ($this->default !== null) {
$spec .= ' DEFAULT %s';
$params[] = $this->default;
$types[] = self::TYPE_VALUE;
}
$options = $this->getOptions();
if (isset($options['on_update'])) {
$spec .= ' %s';
$params[] = 'ON UPDATE CURRENT_TIMESTAMP';
$types[] = self::TYPE_LITERAL;
}
$data = [[
$spec,
$params,
$types,
]];
foreach ($this->constraints as $constraint) {
$data[] = ' ';
$data = array_merge($data, $constraint->getExpressionData());
}
return $data;
}
}
================================================
FILE: src/Zend/Db/src/Sql/Ddl/Column/BigInteger.php
================================================
setName($name);
$this->setNullable($nullable);
$this->setDefault($default);
$this->setOptions($options);
}
/**
* @param string $name
* @return self Provides a fluent interface
*/
public function setName($name)
{
$this->name = (string) $name;
return $this;
}
/**
* @return null|string
*/
public function getName()
{
return $this->name;
}
/**
* @param bool $nullable
* @return self Provides a fluent interface
*/
public function setNullable($nullable)
{
$this->isNullable = (bool) $nullable;
return $this;
}
/**
* @return bool
*/
public function isNullable()
{
return $this->isNullable;
}
/**
* @param null|string|int $default
* @return self Provides a fluent interface
*/
public function setDefault($default)
{
$this->default = $default;
return $this;
}
/**
* @return null|string|int
*/
public function getDefault()
{
return $this->default;
}
/**
* @param array $options
* @return self Provides a fluent interface
*/
public function setOptions(array $options)
{
$this->options = $options;
return $this;
}
/**
* @param string $name
* @param string $value
* @return self Provides a fluent interface
*/
public function setOption($name, $value)
{
$this->options[$name] = $value;
return $this;
}
/**
* @return array
*/
public function getOptions()
{
return $this->options;
}
/**
* @param ConstraintInterface $constraint
*
* @return self Provides a fluent interface
*/
public function addConstraint(ConstraintInterface $constraint)
{
$this->constraints[] = $constraint;
return $this;
}
/**
* @return array
*/
public function getExpressionData()
{
$spec = $this->specification;
$params = [];
$params[] = $this->name;
$params[] = $this->type;
$types = [self::TYPE_IDENTIFIER, self::TYPE_LITERAL];
if (! $this->isNullable) {
$spec .= ' NOT NULL';
}
if ($this->default !== null) {
$spec .= ' DEFAULT %s';
$params[] = $this->default;
$types[] = self::TYPE_VALUE;
}
$data = [[
$spec,
$params,
$types,
]];
foreach ($this->constraints as $constraint) {
$data[] = ' ';
$data = array_merge($data, $constraint->getExpressionData());
}
return $data;
}
}
================================================
FILE: src/Zend/Db/src/Sql/Ddl/Column/ColumnInterface.php
================================================
getOptions();
if (isset($options['length'])) {
$data[0][1][1] .= '(' . $options['length'] . ')';
}
return $data;
}
}
================================================
FILE: src/Zend/Db/src/Sql/Ddl/Column/Text.php
================================================
setColumns($columns);
}
$this->setName($name);
}
/**
* @param string $name
* @return self Provides a fluent interface
*/
public function setName($name)
{
$this->name = (string) $name;
return $this;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @param null|string|array $columns
* @return self Provides a fluent interface
*/
public function setColumns($columns)
{
$this->columns = (array) $columns;
return $this;
}
/**
* @param string $column
* @return self Provides a fluent interface
*/
public function addColumn($column)
{
$this->columns[] = $column;
return $this;
}
/**
* {@inheritDoc}
*/
public function getColumns()
{
return $this->columns;
}
/**
* {@inheritDoc}
*/
public function getExpressionData()
{
$colCount = count($this->columns);
$newSpecTypes = [];
$values = [];
$newSpec = '';
if ($this->name) {
$newSpec .= $this->namedSpecification;
$values[] = $this->name;
$newSpecTypes[] = self::TYPE_IDENTIFIER;
}
$newSpec .= $this->specification;
if ($colCount) {
$values = array_merge($values, $this->columns);
$newSpecParts = array_fill(0, $colCount, '%s');
$newSpecTypes = array_merge($newSpecTypes, array_fill(0, $colCount, self::TYPE_IDENTIFIER));
$newSpec .= sprintf($this->columnSpecification, implode(', ', $newSpecParts));
}
return [[
$newSpec,
$values,
$newSpecTypes,
]];
}
}
================================================
FILE: src/Zend/Db/src/Sql/Ddl/Constraint/Check.php
================================================
expression = $expression;
$this->name = $name;
}
/**
* {@inheritDoc}
*/
public function getExpressionData()
{
$newSpecTypes = [self::TYPE_LITERAL];
$values = [$this->expression];
$newSpec = '';
if ($this->name) {
$newSpec .= $this->namedSpecification;
array_unshift($values, $this->name);
array_unshift($newSpecTypes, self::TYPE_IDENTIFIER);
}
return [[
$newSpec . $this->specification,
$values,
$newSpecTypes,
]];
}
}
================================================
FILE: src/Zend/Db/src/Sql/Ddl/Constraint/ConstraintInterface.php
================================================
setName($name);
$this->setColumns($columns);
$this->setReferenceTable($referenceTable);
$this->setReferenceColumn($referenceColumn);
if ($onDeleteRule) {
$this->setOnDeleteRule($onDeleteRule);
}
if ($onUpdateRule) {
$this->setOnUpdateRule($onUpdateRule);
}
}
/**
* @param string $referenceTable
* @return self Provides a fluent interface
*/
public function setReferenceTable($referenceTable)
{
$this->referenceTable = (string) $referenceTable;
return $this;
}
/**
* @return string
*/
public function getReferenceTable()
{
return $this->referenceTable;
}
/**
* @param null|string|array $referenceColumn
* @return self Provides a fluent interface
*/
public function setReferenceColumn($referenceColumn)
{
$this->referenceColumn = (array) $referenceColumn;
return $this;
}
/**
* @return array
*/
public function getReferenceColumn()
{
return $this->referenceColumn;
}
/**
* @param string $onDeleteRule
* @return self Provides a fluent interface
*/
public function setOnDeleteRule($onDeleteRule)
{
$this->onDeleteRule = (string) $onDeleteRule;
return $this;
}
/**
* @return string
*/
public function getOnDeleteRule()
{
return $this->onDeleteRule;
}
/**
* @param string $onUpdateRule
* @return self Provides a fluent interface
*/
public function setOnUpdateRule($onUpdateRule)
{
$this->onUpdateRule = (string) $onUpdateRule;
return $this;
}
/**
* @return string
*/
public function getOnUpdateRule()
{
return $this->onUpdateRule;
}
/**
* @return array
*/
public function getExpressionData()
{
$data = parent::getExpressionData();
$colCount = count($this->referenceColumn);
$newSpecTypes = [self::TYPE_IDENTIFIER];
$values = [$this->referenceTable];
$data[0][0] .= $this->referenceSpecification[0];
if ($colCount) {
$values = array_merge($values, $this->referenceColumn);
$newSpecParts = array_fill(0, $colCount, '%s');
$newSpecTypes = array_merge($newSpecTypes, array_fill(0, $colCount, self::TYPE_IDENTIFIER));
$data[0][0] .= sprintf('(%s) ', implode(', ', $newSpecParts));
}
$data[0][0] .= $this->referenceSpecification[1];
$values[] = $this->onDeleteRule;
$values[] = $this->onUpdateRule;
$newSpecTypes[] = self::TYPE_LITERAL;
$newSpecTypes[] = self::TYPE_LITERAL;
$data[0][1] = array_merge($data[0][1], $values);
$data[0][2] = array_merge($data[0][2], $newSpecTypes);
return $data;
}
}
================================================
FILE: src/Zend/Db/src/Sql/Ddl/Constraint/PrimaryKey.php
================================================
'CREATE %1$sTABLE %2$s (',
self::COLUMNS => [
"\n %1\$s" => [
[1 => '%1$s', 'combinedby' => ",\n "]
]
],
'combinedBy' => ",",
self::CONSTRAINTS => [
"\n %1\$s" => [
[1 => '%1$s', 'combinedby' => ",\n "]
]
],
'statementEnd' => '%1$s',
];
/**
* @var string
*/
protected $table = '';
/**
* @param string|TableIdentifier $table
* @param bool $isTemporary
*/
public function __construct($table = '', $isTemporary = false)
{
$this->table = $table;
$this->setTemporary($isTemporary);
}
/**
* @param bool $temporary
* @return self Provides a fluent interface
*/
public function setTemporary($temporary)
{
$this->isTemporary = (bool) $temporary;
return $this;
}
/**
* @return bool
*/
public function isTemporary()
{
return $this->isTemporary;
}
/**
* @param string $name
* @return self Provides a fluent interface
*/
public function setTable($name)
{
$this->table = $name;
return $this;
}
/**
* @param Column\ColumnInterface $column
* @return self Provides a fluent interface
*/
public function addColumn(Column\ColumnInterface $column)
{
$this->columns[] = $column;
return $this;
}
/**
* @param Constraint\ConstraintInterface $constraint
* @return self Provides a fluent interface
*/
public function addConstraint(Constraint\ConstraintInterface $constraint)
{
$this->constraints[] = $constraint;
return $this;
}
/**
* @param string|null $key
* @return array
*/
public function getRawState($key = null)
{
$rawState = [
self::COLUMNS => $this->columns,
self::CONSTRAINTS => $this->constraints,
self::TABLE => $this->table,
];
return (isset($key) && array_key_exists($key, $rawState)) ? $rawState[$key] : $rawState;
}
/**
* @param PlatformInterface|null $adapterPlatform
*
* @return string[]
*/
protected function processTable(?PlatformInterface $adapterPlatform = null)
{
return [
$this->isTemporary ? 'TEMPORARY ' : '',
$this->resolveTable($this->table, $adapterPlatform),
];
}
/**
* @param PlatformInterface|null $adapterPlatform
*
* @return string[][]|null
*/
protected function processColumns(?PlatformInterface $adapterPlatform = null)
{
if (! $this->columns) {
return;
}
$sqls = [];
foreach ($this->columns as $column) {
$sqls[] = $this->processExpression($column, $adapterPlatform);
}
return [$sqls];
}
/**
*
* @return array|string
*/
protected function processCombinedby()
{
if ($this->constraints && $this->columns) {
return $this->specifications['combinedBy'];
}
}
/**
* @param PlatformInterface|null $adapterPlatform
*
* @return string[][]|null
*/
protected function processConstraints(?PlatformInterface $adapterPlatform = null)
{
if (! $this->constraints) {
return;
}
$sqls = [];
foreach ($this->constraints as $constraint) {
$sqls[] = $this->processExpression($constraint, $adapterPlatform);
}
return [$sqls];
}
/**
*
* @return string[]
*/
protected function processStatementEnd()
{
return ["\n)"];
}
}
================================================
FILE: src/Zend/Db/src/Sql/Ddl/DropTable.php
================================================
'DROP TABLE %1$s'
];
/**
* @var string
*/
protected $table = '';
/**
* @param string|TableIdentifier $table
*/
public function __construct($table = '')
{
$this->table = $table;
}
protected function processTable(?PlatformInterface $adapterPlatform = null)
{
return [$this->resolveTable($this->table, $adapterPlatform)];
}
}
================================================
FILE: src/Zend/Db/src/Sql/Ddl/Index/AbstractIndex.php
================================================
setColumns($columns);
$this->name = null === $name ? null : (string) $name;
$this->lengths = $lengths;
}
/**
*
* @return array of array|string should return an array in the format:
*
* array (
* // a sprintf formatted string
* string $specification,
*
* // the values for the above sprintf formatted string
* array $values,
*
* // an array of equal length of the $values array, with either TYPE_IDENTIFIER or TYPE_VALUE for each value
* array $types,
* )
*
*/
public function getExpressionData()
{
$colCount = count($this->columns);
$values = [];
$values[] = $this->name ?: '';
$newSpecTypes = [self::TYPE_IDENTIFIER];
$newSpecParts = [];
for ($i = 0; $i < $colCount; $i++) {
$specPart = '%s';
if (isset($this->lengths[$i])) {
$specPart .= "({$this->lengths[$i]})";
}
$newSpecParts[] = $specPart;
$newSpecTypes[] = self::TYPE_IDENTIFIER;
}
$newSpec = str_replace('...', implode(', ', $newSpecParts), $this->specification);
return [[
$newSpec,
array_merge($values, $this->columns),
$newSpecTypes,
]];
}
}
================================================
FILE: src/Zend/Db/src/Sql/Ddl/SqlInterface.php
================================================
'DELETE FROM %1$s',
self::SPECIFICATION_WHERE => 'WHERE %1$s'
];
/**
* @var string|TableIdentifier
*/
protected $table = '';
/**
* @var bool
*/
protected $emptyWhereProtection = true;
/**
* @var array
*/
protected $set = [];
/**
* @var null|string|Where
*/
protected $where = null;
/**
* Constructor
*
* @param null|string|TableIdentifier $table
*/
public function __construct($table = null)
{
if ($table) {
$this->from($table);
}
$this->where = new Where();
}
/**
* Create from statement
*
* @param string|TableIdentifier $table
* @return self Provides a fluent interface
*/
public function from($table)
{
$this->table = $table;
return $this;
}
/**
* @param null $key
*
* @return mixed
*/
public function getRawState($key = null)
{
$rawState = [
'emptyWhereProtection' => $this->emptyWhereProtection,
'table' => $this->table,
'set' => $this->set,
'where' => $this->where
];
return (isset($key) && array_key_exists($key, $rawState)) ? $rawState[$key] : $rawState;
}
/**
* Create where clause
*
* @param Where|\Closure|string|array $predicate
* @param string $combination One of the OP_* constants from Predicate\PredicateSet
*
* @return self Provides a fluent interface
*/
public function where($predicate, $combination = Predicate\PredicateSet::OP_AND)
{
if ($predicate instanceof Where) {
$this->where = $predicate;
} else {
$this->where->addPredicates($predicate, $combination);
}
return $this;
}
/**
* @param PlatformInterface $platform
* @param DriverInterface|null $driver
* @param ParameterContainer|null $parameterContainer
*
* @return string
*/
protected function processDelete(
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
return sprintf(
$this->specifications[static::SPECIFICATION_DELETE],
$this->resolveTable($this->table, $platform, $driver, $parameterContainer)
);
}
/**
* @param PlatformInterface $platform
* @param DriverInterface|null $driver
* @param ParameterContainer|null $parameterContainer
*
* @return null|string
*/
protected function processWhere(
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
if ($this->where->count() == 0) {
return;
}
return sprintf(
$this->specifications[static::SPECIFICATION_WHERE],
$this->processExpression($this->where, $platform, $driver, $parameterContainer, 'where')
);
}
/**
* Property overloading
*
* Overloads "where" only.
*
* @param string $name
*
* @return Where|null
*/
public function __get($name)
{
switch (strtolower($name)) {
case 'where':
return $this->where;
}
}
}
================================================
FILE: src/Zend/Db/src/Sql/Exception/ExceptionInterface.php
================================================
setExpression($expression);
}
if ($types) { // should be deprecated and removed version 3.0.0
if (is_array($parameters)) {
foreach ($parameters as $i => $parameter) {
$parameters[$i] = [
$parameter => $types[$i] ?? self::TYPE_VALUE,
];
}
} elseif (is_scalar($parameters)) {
$parameters = [
$parameters => $types[0],
];
}
}
if ($parameters !== null) {
$this->setParameters($parameters);
}
}
/**
* @param $expression
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function setExpression($expression)
{
if (! is_string($expression) || $expression == '') {
throw new Exception\InvalidArgumentException('Supplied expression must be a string.');
}
$this->expression = $expression;
return $this;
}
/**
* @return string
*/
public function getExpression()
{
return $this->expression;
}
/**
* @param $parameters
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function setParameters($parameters)
{
if (! is_scalar($parameters) && ! is_array($parameters)) {
throw new Exception\InvalidArgumentException('Expression parameters must be a scalar or array.');
}
$this->parameters = $parameters;
return $this;
}
/**
* @return array
*/
public function getParameters()
{
return $this->parameters;
}
/**
* @deprecated
* @param array $types
* @return self Provides a fluent interface
*/
public function setTypes(array $types)
{
$this->types = $types;
return $this;
}
/**
* @deprecated
* @return array
*/
public function getTypes()
{
return $this->types;
}
/**
* @return array
* @throws Exception\RuntimeException
*/
public function getExpressionData()
{
$parameters = (is_scalar($this->parameters)) ? [$this->parameters] : $this->parameters;
$parametersCount = count($parameters);
$expression = str_replace('%', '%%', $this->expression);
if ($parametersCount === 0) {
return [
str_ireplace(self::PLACEHOLDER, '', $expression)
];
}
// assign locally, escaping % signs
$expression = str_replace(self::PLACEHOLDER, '%s', $expression, $count);
// test number of replacements without considering same variable begin used many times first, which is
// faster, if the test fails then resort to regex which are slow and used rarely
if ($count !== $parametersCount) {
preg_match_all('/\:\w*/', $expression, $matches);
if ($parametersCount !== count(array_unique($matches[0]))) {
throw new Exception\RuntimeException(
'The number of replacements in the expression does not match the number of parameters'
);
}
}
foreach ($parameters as $parameter) {
list($values[], $types[]) = $this->normalizeArgument($parameter, self::TYPE_VALUE);
}
return [[
$expression,
$values,
$types
]];
}
}
================================================
FILE: src/Zend/Db/src/Sql/ExpressionInterface.php
================================================
'INSERT INTO %1$s (%2$s) VALUES (%3$s)',
self::SPECIFICATION_SELECT => 'INSERT INTO %1$s %2$s %3$s',
];
/**
* @var string|TableIdentifier
*/
protected $table = null;
protected $columns = [];
/**
* @var array|Select
*/
protected $select = null;
/**
* Constructor
*
* @param null|string|TableIdentifier $table
*/
public function __construct($table = null)
{
if ($table) {
$this->into($table);
}
}
/**
* Create INTO clause
*
* @param string|TableIdentifier $table
* @return self Provides a fluent interface
*/
public function into($table)
{
$this->table = $table;
return $this;
}
/**
* Specify columns
*
* @param array $columns
* @return self Provides a fluent interface
*/
public function columns(array $columns)
{
$this->columns = array_flip($columns);
return $this;
}
/**
* Specify values to insert
*
* @param array|Select $values
* @param string $flag one of VALUES_MERGE or VALUES_SET; defaults to VALUES_SET
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function values($values, $flag = self::VALUES_SET)
{
if ($values instanceof Select) {
if ($flag == self::VALUES_MERGE) {
throw new Exception\InvalidArgumentException(
'A Zend\Db\Sql\Select instance cannot be provided with the merge flag'
);
}
$this->select = $values;
return $this;
}
if (! is_array($values)) {
throw new Exception\InvalidArgumentException(
'values() expects an array of values or Zend\Db\Sql\Select instance'
);
}
if ($this->select && $flag == self::VALUES_MERGE) {
throw new Exception\InvalidArgumentException(
'An array of values cannot be provided with the merge flag when a Zend\Db\Sql\Select instance already '
. 'exists as the value source'
);
}
if ($flag == self::VALUES_SET) {
$this->columns = $this->isAssocativeArray($values)
? $values
: array_combine(array_keys($this->columns), array_values($values));
} else {
foreach ($values as $column => $value) {
$this->columns[$column] = $value;
}
}
return $this;
}
/**
* Simple test for an associative array
*
* @link http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential
* @param array $array
* @return bool
*/
private function isAssocativeArray(array $array)
{
return array_keys($array) !== range(0, count($array) - 1);
}
/**
* Create INTO SELECT clause
*
* @param Select $select
* @return self
*/
public function select(Select $select)
{
return $this->values($select);
}
/**
* Get raw state
*
* @param string $key
* @return mixed
*/
public function getRawState($key = null)
{
$rawState = [
'table' => $this->table,
'columns' => array_keys($this->columns),
'values' => array_values($this->columns)
];
return (isset($key) && array_key_exists($key, $rawState)) ? $rawState[$key] : $rawState;
}
protected function processInsert(
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
if ($this->select) {
return;
}
if (! $this->columns) {
throw new Exception\InvalidArgumentException('values or select should be present');
}
$columns = [];
$values = [];
$i = 0;
foreach ($this->columns as $column => $value) {
$columns[] = $platform->quoteIdentifier($column);
if (is_scalar($value) && $parameterContainer) {
// use incremental value instead of column name for PDO
// @see https://github.com/zendframework/zend-db/issues/35
if ($driver instanceof Pdo) {
$column = 'c_' . $i++;
}
$values[] = $driver->formatParameterName($column);
$parameterContainer->offsetSet($column, $value);
} else {
$values[] = $this->resolveColumnValue(
$value,
$platform,
$driver,
$parameterContainer
);
}
}
return sprintf(
$this->specifications[static::SPECIFICATION_INSERT],
$this->resolveTable($this->table, $platform, $driver, $parameterContainer),
implode(', ', $columns),
implode(', ', $values)
);
}
protected function processSelect(
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
if (! $this->select) {
return;
}
$selectSql = $this->processSubSelect($this->select, $platform, $driver, $parameterContainer);
$columns = array_map([$platform, 'quoteIdentifier'], array_keys($this->columns));
$columns = implode(', ', $columns);
return sprintf(
$this->specifications[static::SPECIFICATION_SELECT],
$this->resolveTable($this->table, $platform, $driver, $parameterContainer),
$columns ? "($columns)" : "",
$selectSql
);
}
/**
* Overloading: variable setting
*
* Proxies to values, using VALUES_MERGE strategy
*
* @param string $name
* @param mixed $value
* @return self Provides a fluent interface
*/
public function __set($name, $value)
{
$this->columns[$name] = $value;
return $this;
}
/**
* Overloading: variable unset
*
* Proxies to values and columns
*
* @param string $name
* @throws Exception\InvalidArgumentException
* @return void
*/
public function __unset($name)
{
if (! array_key_exists($name, $this->columns)) {
throw new Exception\InvalidArgumentException(
'The key ' . $name . ' was not found in this objects column list'
);
}
unset($this->columns[$name]);
}
/**
* Overloading: variable isset
*
* Proxies to columns; does a column of that name exist?
*
* @param string $name
* @return bool
*/
public function __isset($name)
{
return array_key_exists($name, $this->columns);
}
/**
* Overloading: variable retrieval
*
* Retrieves value by column name
*
* @param string $name
* @throws Exception\InvalidArgumentException
* @return mixed
*/
public function __get($name)
{
if (! array_key_exists($name, $this->columns)) {
throw new Exception\InvalidArgumentException(
'The key ' . $name . ' was not found in this objects column list'
);
}
return $this->columns[$name];
}
}
================================================
FILE: src/Zend/Db/src/Sql/InsertIgnore.php
================================================
'INSERT IGNORE INTO %1$s (%2$s) VALUES (%3$s)',
self::SPECIFICATION_SELECT => 'INSERT IGNORE INTO %1$s %2$s %3$s',
];
}
================================================
FILE: src/Zend/Db/src/Sql/Join.php
================================================
position = 0;
}
/**
* Rewind iterator.
*/
#[ReturnTypeWillChange] public function rewind()
{
$this->position = 0;
}
/**
* Return current join specification.
*
* @return array
*/
#[ReturnTypeWillChange] public function current()
{
return $this->joins[$this->position];
}
/**
* Return the current iterator index.
*
* @return int
*/
#[ReturnTypeWillChange] public function key()
{
return $this->position;
}
/**
* Advance to the next JOIN specification.
*/
#[ReturnTypeWillChange] public function next()
{
++$this->position;
}
/**
* Is the iterator at a valid position?
*
* @return bool
*/
#[ReturnTypeWillChange] public function valid()
{
return isset($this->joins[$this->position]);
}
/**
* @return array
*/
public function getJoins()
{
return $this->joins;
}
/**
* @param string|array|TableIdentifier $name A table name on which to join, or a single
* element associative array, of the form alias => table, or TableIdentifier instance
* @param string|Predicate\Expression $on A specification describing the fields to join on.
* @param string|string[]|int|int[] $columns A single column name, an array
* of column names, or (a) specification(s) such as SQL_STAR representing
* the columns to join.
* @param string $type The JOIN type to use; see the JOIN_* constants.
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException for invalid $name values.
*/
public function join($name, $on, $columns = [Select::SQL_STAR], $type = Join::JOIN_INNER)
{
if (is_array($name) && (! is_string(key($name)) || count($name) !== 1)) {
throw new Exception\InvalidArgumentException(
sprintf("join() expects '%s' as a single element associative array", array_shift($name))
);
}
if (! is_array($columns)) {
$columns = [$columns];
}
$this->joins[] = [
'name' => $name,
'on' => $on,
'columns' => $columns,
'type' => $type ? $type : Join::JOIN_INNER
];
return $this;
}
/**
* Reset to an empty list of JOIN specifications.
*
* @return self Provides a fluent interface
*/
public function reset()
{
$this->joins = [];
return $this;
}
/**
* Get count of attached predicates
*
* @return int
*/
#[ReturnTypeWillChange] public function count()
{
return count($this->joins);
}
}
================================================
FILE: src/Zend/Db/src/Sql/Literal.php
================================================
literal = $literal;
}
/**
* @param string $literal
* @return self Provides a fluent interface
*/
public function setLiteral($literal)
{
$this->literal = $literal;
return $this;
}
/**
* @return string
*/
public function getLiteral()
{
return $this->literal;
}
/**
* @return array
*/
public function getExpressionData()
{
return [[
str_replace('%', '%%', $this->literal),
[],
[]
]];
}
}
================================================
FILE: src/Zend/Db/src/Sql/Platform/AbstractPlatform.php
================================================
subject = $subject;
return $this;
}
/**
* @param string $type
* @param PlatformDecoratorInterface $decorator
*
* @return void
*/
public function setTypeDecorator($type, PlatformDecoratorInterface $decorator)
{
$this->decorators[$type] = $decorator;
}
/**
* @param PreparableSqlInterface|SqlInterface $subject
* @return PlatformDecoratorInterface|PreparableSqlInterface|SqlInterface
*/
public function getTypeDecorator($subject)
{
foreach ($this->decorators as $type => $decorator) {
if ($subject instanceof $type) {
$decorator->setSubject($subject);
return $decorator;
}
}
return $subject;
}
/**
* @return array|PlatformDecoratorInterface[]
*/
public function getDecorators()
{
return $this->decorators;
}
/**
* {@inheritDoc}
*
* @throws Exception\RuntimeException
*/
public function prepareStatement(AdapterInterface $adapter, StatementContainerInterface $statementContainer)
{
if (! $this->subject instanceof PreparableSqlInterface) {
throw new Exception\RuntimeException(
'The subject does not appear to implement Zend\Db\Sql\PreparableSqlInterface, thus calling '
. 'prepareStatement() has no effect'
);
}
$this->getTypeDecorator($this->subject)->prepareStatement($adapter, $statementContainer);
return $statementContainer;
}
/**
* {@inheritDoc}
*
* @throws Exception\RuntimeException
*/
public function getSqlString(?PlatformInterface $adapterPlatform = null)
{
if (! $this->subject instanceof SqlInterface) {
throw new Exception\RuntimeException(
'The subject does not appear to implement Zend\Db\Sql\SqlInterface, thus calling '
. 'prepareStatement() has no effect'
);
}
return $this->getTypeDecorator($this->subject)->getSqlString($adapterPlatform);
}
}
================================================
FILE: src/Zend/Db/src/Sql/Platform/IbmDb2/IbmDb2.php
================================================
setTypeDecorator('Zend\Db\Sql\Select', ($selectDecorator) ?: new SelectDecorator());
}
}
================================================
FILE: src/Zend/Db/src/Sql/Platform/IbmDb2/SelectDecorator.php
================================================
isSelectContainDistinct;
}
/**
* @param boolean $isSelectContainDistinct
*/
public function setIsSelectContainDistinct($isSelectContainDistinct)
{
$this->isSelectContainDistinct = $isSelectContainDistinct;
}
/**
* @param Select $select
*/
public function setSubject($select)
{
$this->subject = $select;
}
/**
* @return bool
*/
public function getSupportsLimitOffset()
{
return $this->supportsLimitOffset;
}
/**
* @param bool $supportsLimitOffset
*/
public function setSupportsLimitOffset($supportsLimitOffset)
{
$this->supportsLimitOffset = $supportsLimitOffset;
}
/**
* @see Select::renderTable
*/
protected function renderTable($table, $alias = null)
{
return $table . ' ' . $alias;
}
protected function localizeVariables()
{
parent::localizeVariables();
// set specifications
unset($this->specifications[self::LIMIT]);
unset($this->specifications[self::OFFSET]);
$this->specifications['LIMITOFFSET'] = null;
}
/**
* @param PlatformInterface $platform
* @param DriverInterface|null $driver
* @param ParameterContainer|null $parameterContainer
* @param array $sqls
* @param array $parameters
*/
protected function processLimitOffset(
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null,
&$sqls = [],
&$parameter = [],
) {
if ($this->limit === null && $this->offset === null) {
return;
}
if ($this->supportsLimitOffset) {
// Note: db2_prepare/db2_execute fails with positional parameters, for LIMIT & OFFSET
$limit = (int) $this->limit;
if (! $limit) {
return;
}
$offset = (int) $this->offset;
if ($offset) {
$sqls[] = sprintf("LIMIT %s OFFSET %s", $limit, $offset);
return;
}
$sqls[] = sprintf("LIMIT %s", $limit);
return;
}
$selectParameters = $parameters[self::SELECT];
$starSuffix = $platform->getIdentifierSeparator() . self::SQL_STAR;
foreach ($selectParameters[0] as $i => $columnParameters) {
if ($columnParameters[0] == self::SQL_STAR
|| (isset($columnParameters[1]) && $columnParameters[1] == self::SQL_STAR)
|| strpos($columnParameters[0], $starSuffix)
) {
$selectParameters[0] = [[self::SQL_STAR]];
break;
}
if (isset($columnParameters[1])) {
array_shift($columnParameters);
$selectParameters[0][$i] = $columnParameters;
}
}
// first, produce column list without compound names (using the AS portion only)
array_unshift($sqls, $this->createSqlFromSpecificationAndParameters(
['SELECT %1$s FROM (' => current($this->specifications[self::SELECT])],
$selectParameters
));
if (preg_match('/DISTINCT/i', $sqls[0])) {
$this->setIsSelectContainDistinct(true);
}
if ($parameterContainer) {
// create bottom part of query, with offset and limit using row_number
$limitParamName = $driver->formatParameterName('limit');
$offsetParamName = $driver->formatParameterName('offset');
$sqls[] = sprintf(
// @codingStandardsIgnoreStart
") AS ZEND_IBMDB2_SERVER_LIMIT_OFFSET_EMULATION WHERE ZEND_IBMDB2_SERVER_LIMIT_OFFSET_EMULATION.ZEND_DB_ROWNUM BETWEEN %s AND %s",
// @codingStandardsIgnoreEnd
$offsetParamName,
$limitParamName
);
if ((int) $this->offset > 0) {
$parameterContainer->offsetSet('offset', (int) $this->offset + 1);
} else {
$parameterContainer->offsetSet('offset', (int) $this->offset);
}
$parameterContainer->offsetSet('limit', (int) $this->limit + (int) $this->offset);
} else {
if ((int) $this->offset > 0) {
$offset = (int) $this->offset + 1;
} else {
$offset = (int) $this->offset;
}
$sqls[] = sprintf(
// @codingStandardsIgnoreStart
") AS ZEND_IBMDB2_SERVER_LIMIT_OFFSET_EMULATION WHERE ZEND_IBMDB2_SERVER_LIMIT_OFFSET_EMULATION.ZEND_DB_ROWNUM BETWEEN %d AND %d",
// @codingStandardsIgnoreEnd
$offset,
(int) $this->limit + (int) $this->offset
);
}
if (isset($sqls[self::ORDER])) {
$orderBy = $sqls[self::ORDER];
unset($sqls[self::ORDER]);
} else {
$orderBy = '';
}
// add a column for row_number() using the order specification //dense_rank()
if ($this->getIsSelectContainDistinct()) {
$parameters[self::SELECT][0][] = ['DENSE_RANK() OVER (' . $orderBy . ')', 'ZEND_DB_ROWNUM'];
} else {
$parameters[self::SELECT][0][] = ['ROW_NUMBER() OVER (' . $orderBy . ')', 'ZEND_DB_ROWNUM'];
}
$sqls[self::SELECT] = $this->createSqlFromSpecificationAndParameters(
$this->specifications[self::SELECT],
$parameters[self::SELECT]
);
}
}
================================================
FILE: src/Zend/Db/src/Sql/Platform/Mysql/Ddl/AlterTableDecorator.php
================================================
0,
'zerofill' => 1,
'identity' => 2,
'serial' => 2,
'autoincrement' => 2,
'comment' => 3,
'columnformat' => 4,
'format' => 4,
'storage' => 5,
'after' => 6
];
/**
* @param AlterTable $subject
* @return self Provides a fluent interface
*/
public function setSubject($subject)
{
$this->subject = $subject;
return $this;
}
/**
* @param string $sql
* @return array
*/
protected function getSqlInsertOffsets($sql)
{
$sqlLength = strlen($sql);
$insertStart = [];
foreach (['NOT NULL', 'NULL', 'DEFAULT', 'UNIQUE', 'PRIMARY', 'REFERENCES'] as $needle) {
$insertPos = strpos($sql, ' ' . $needle);
if ($insertPos !== false) {
switch ($needle) {
case 'REFERENCES':
$insertStart[2] = ! isset($insertStart[2]) ? $insertPos : $insertStart[2];
// no break
case 'PRIMARY':
case 'UNIQUE':
$insertStart[1] = ! isset($insertStart[1]) ? $insertPos : $insertStart[1];
// no break
default:
$insertStart[0] = ! isset($insertStart[0]) ? $insertPos : $insertStart[0];
}
}
}
foreach (range(0, 3) as $i) {
$insertStart[$i] = $insertStart[$i] ?? $sqlLength;
}
return $insertStart;
}
/**
* @param PlatformInterface|null $adapterPlatform
* @return array
*/
protected function processAddColumns(?PlatformInterface $adapterPlatform = null)
{
$sqls = [];
foreach ($this->addColumns as $i => $column) {
$sql = $this->processExpression($column, $adapterPlatform);
$insertStart = $this->getSqlInsertOffsets($sql);
$columnOptions = $column->getOptions();
uksort($columnOptions, [$this, 'compareColumnOptions']);
foreach ($columnOptions as $coName => $coValue) {
$insert = '';
if (! $coValue) {
continue;
}
switch ($this->normalizeColumnOption($coName)) {
case 'unsigned':
$insert = ' UNSIGNED';
$j = 0;
break;
case 'zerofill':
$insert = ' ZEROFILL';
$j = 0;
break;
case 'identity':
case 'serial':
case 'autoincrement':
$insert = ' AUTO_INCREMENT';
$j = 1;
break;
case 'comment':
$insert = ' COMMENT ' . $adapterPlatform->quoteValue($coValue);
$j = 2;
break;
case 'columnformat':
case 'format':
$insert = ' COLUMN_FORMAT ' . strtoupper($coValue);
$j = 2;
break;
case 'storage':
$insert = ' STORAGE ' . strtoupper($coValue);
$j = 2;
break;
case 'after':
$insert = ' AFTER ' . $adapterPlatform->quoteIdentifier($coValue);
$j = 2;
}
if ($insert) {
$j = $j ?? 0;
$sql = substr_replace($sql, $insert, $insertStart[$j], 0);
$insertStartCount = count($insertStart);
for (; $j < $insertStartCount; ++$j) {
$insertStart[$j] += strlen($insert);
}
}
}
$sqls[$i] = $sql;
}
return [$sqls];
}
/**
* @param PlatformInterface|null $adapterPlatform
* @return array
*/
protected function processChangeColumns(?PlatformInterface $adapterPlatform = null)
{
$sqls = [];
foreach ($this->changeColumns as $name => $column) {
$sql = $this->processExpression($column, $adapterPlatform);
$insertStart = $this->getSqlInsertOffsets($sql);
$columnOptions = $column->getOptions();
uksort($columnOptions, [$this, 'compareColumnOptions']);
foreach ($columnOptions as $coName => $coValue) {
$insert = '';
if (! $coValue) {
continue;
}
switch ($this->normalizeColumnOption($coName)) {
case 'unsigned':
$insert = ' UNSIGNED';
$j = 0;
break;
case 'zerofill':
$insert = ' ZEROFILL';
$j = 0;
break;
case 'identity':
case 'serial':
case 'autoincrement':
$insert = ' AUTO_INCREMENT';
$j = 1;
break;
case 'comment':
$insert = ' COMMENT ' . $adapterPlatform->quoteValue($coValue);
$j = 2;
break;
case 'columnformat':
case 'format':
$insert = ' COLUMN_FORMAT ' . strtoupper($coValue);
$j = 2;
break;
case 'storage':
$insert = ' STORAGE ' . strtoupper($coValue);
$j = 2;
break;
}
if ($insert) {
$j = $j ?? 0;
$sql = substr_replace($sql, $insert, $insertStart[$j], 0);
$insertStartCount = count($insertStart);
for (; $j < $insertStartCount; ++$j) {
$insertStart[$j] += strlen($insert);
}
}
}
$sqls[] = [
$adapterPlatform->quoteIdentifier($name),
$sql
];
}
return [$sqls];
}
/**
* @param string $name
*
* @return string
*/
private function normalizeColumnOption($name)
{
return strtolower(str_replace(['-', '_', ' '], '', $name));
}
/**
*
* @param string $columnA
* @param string $columnB
*
* @return int
*/
private function compareColumnOptions($columnA, $columnB)
{
$columnA = $this->normalizeColumnOption($columnA);
$columnA = $this->columnOptionSortOrder[$columnA] ?? count($this->columnOptionSortOrder);
$columnB = $this->normalizeColumnOption($columnB);
$columnB = $this->columnOptionSortOrder[$columnB] ?? count($this->columnOptionSortOrder);
return $columnA - $columnB;
}
}
================================================
FILE: src/Zend/Db/src/Sql/Platform/Mysql/Ddl/CreateTableDecorator.php
================================================
0,
'zerofill' => 1,
'identity' => 2,
'serial' => 2,
'autoincrement' => 2,
'comment' => 3,
'columnformat' => 4,
'format' => 4,
'storage' => 5,
];
/**
* @param CreateTable $subject
*
* @return self Provides a fluent interface
*/
public function setSubject($subject)
{
$this->subject = $subject;
return $this;
}
/**
* @param string $sql
* @return array
*/
protected function getSqlInsertOffsets($sql)
{
$sqlLength = strlen($sql);
$insertStart = [];
foreach (['NOT NULL', 'NULL', 'DEFAULT', 'UNIQUE', 'PRIMARY', 'REFERENCES'] as $needle) {
$insertPos = strpos($sql, ' ' . $needle);
if ($insertPos !== false) {
switch ($needle) {
case 'REFERENCES':
$insertStart[2] = ! isset($insertStart[2]) ? $insertPos : $insertStart[2];
// no break
case 'PRIMARY':
case 'UNIQUE':
$insertStart[1] = ! isset($insertStart[1]) ? $insertPos : $insertStart[1];
// no break
default:
$insertStart[0] = ! isset($insertStart[0]) ? $insertPos : $insertStart[0];
}
}
}
foreach (range(0, 3) as $i) {
$insertStart[$i] = $insertStart[$i] ?? $sqlLength;
}
return $insertStart;
}
/**
* {@inheritDoc}
*/
protected function processColumns(?PlatformInterface $platform = null)
{
if (! $this->columns) {
return;
}
$sqls = [];
foreach ($this->columns as $i => $column) {
$sql = $this->processExpression($column, $platform);
$insertStart = $this->getSqlInsertOffsets($sql);
$columnOptions = $column->getOptions();
uksort($columnOptions, [$this, 'compareColumnOptions']);
foreach ($columnOptions as $coName => $coValue) {
$insert = '';
if (! $coValue) {
continue;
}
switch ($this->normalizeColumnOption($coName)) {
case 'unsigned':
$insert = ' UNSIGNED';
$j = 0;
break;
case 'zerofill':
$insert = ' ZEROFILL';
$j = 0;
break;
case 'identity':
case 'serial':
case 'autoincrement':
$insert = ' AUTO_INCREMENT';
$j = 1;
break;
case 'comment':
$insert = ' COMMENT ' . $platform->quoteValue($coValue);
$j = 2;
break;
case 'columnformat':
case 'format':
$insert = ' COLUMN_FORMAT ' . strtoupper($coValue);
$j = 2;
break;
case 'storage':
$insert = ' STORAGE ' . strtoupper($coValue);
$j = 2;
break;
}
if ($insert) {
$j = $j ?? 0;
$sql = substr_replace($sql, $insert, $insertStart[$j], 0);
$insertStartCount = count($insertStart);
for (; $j < $insertStartCount; ++$j) {
$insertStart[$j] += strlen($insert);
}
}
}
$sqls[$i] = $sql;
}
return [$sqls];
}
/**
* @param string $name
*
* @return string
*/
private function normalizeColumnOption($name)
{
return strtolower(str_replace(['-', '_', ' '], '', $name));
}
/**
*
* @param string $columnA
* @param string $columnB
*
* @return int
*/
private function compareColumnOptions($columnA, $columnB)
{
$columnA = $this->normalizeColumnOption($columnA);
$columnA = $this->columnOptionSortOrder[$columnA] ?? count($this->columnOptionSortOrder);
$columnB = $this->normalizeColumnOption($columnB);
$columnB = $this->columnOptionSortOrder[$columnB] ?? count($this->columnOptionSortOrder);
return $columnA - $columnB;
}
}
================================================
FILE: src/Zend/Db/src/Sql/Platform/Mysql/Mysql.php
================================================
setTypeDecorator('Zend\Db\Sql\Select', new SelectDecorator());
$this->setTypeDecorator('Zend\Db\Sql\Ddl\CreateTable', new Ddl\CreateTableDecorator());
$this->setTypeDecorator('Zend\Db\Sql\Ddl\AlterTable', new Ddl\AlterTableDecorator());
}
}
================================================
FILE: src/Zend/Db/src/Sql/Platform/Mysql/SelectDecorator.php
================================================
subject = $select;
}
protected function localizeVariables()
{
parent::localizeVariables();
if ($this->limit === null && $this->offset !== null) {
$this->specifications[self::LIMIT] = 'LIMIT 18446744073709551615';
}
}
protected function processLimit(
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
if ($this->limit === null && $this->offset !== null) {
return [''];
}
if ($this->limit === null) {
return;
}
if ($parameterContainer) {
$paramPrefix = $this->processInfo['paramPrefix'];
$parameterContainer->offsetSet($paramPrefix . 'limit', $this->limit, ParameterContainer::TYPE_INTEGER);
return [$driver->formatParameterName($paramPrefix . 'limit')];
}
return [$this->limit];
}
protected function processOffset(
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
if ($this->offset === null) {
return;
}
if ($parameterContainer) {
$paramPrefix = $this->processInfo['paramPrefix'];
$parameterContainer->offsetSet($paramPrefix . 'offset', $this->offset, ParameterContainer::TYPE_INTEGER);
return [$driver->formatParameterName($paramPrefix . 'offset')];
}
return [$this->offset];
}
}
================================================
FILE: src/Zend/Db/src/Sql/Platform/Oracle/Oracle.php
================================================
setTypeDecorator('Zend\Db\Sql\Select', ($selectDecorator) ?: new SelectDecorator());
}
}
================================================
FILE: src/Zend/Db/src/Sql/Platform/Oracle/SelectDecorator.php
================================================
subject = $select;
}
/**
* @see \Zend\Db\Sql\Select::renderTable
*/
protected function renderTable($table, $alias = null)
{
return $table . ($alias ? ' ' . $alias : '');
}
protected function localizeVariables()
{
parent::localizeVariables();
unset($this->specifications[self::LIMIT]);
unset($this->specifications[self::OFFSET]);
$this->specifications['LIMITOFFSET'] = null;
}
/**
* @param PlatformInterface $platform
* @param ParameterContainer|null $parameterContainer
* @param array $sqls
* @param array $parameters
* @return null
*/
protected function processLimitOffset(
PlatformInterface $platform,
?ParameterContainer $parameterContainer = null,
&$sqls = [],
$parameters = []
) {
if ($this->limit === null && $this->offset === null) {
return;
}
$selectParameters = $parameters[self::SELECT];
$starSuffix = $platform->getIdentifierSeparator() . self::SQL_STAR;
foreach ($selectParameters[0] as $i => $columnParameters) {
if ($columnParameters[0] == self::SQL_STAR
|| (isset($columnParameters[1]) && $columnParameters[1] == self::SQL_STAR)
|| strpos($columnParameters[0], $starSuffix)
) {
$selectParameters[0] = [[self::SQL_STAR]];
break;
}
if (isset($columnParameters[1])) {
array_shift($columnParameters);
$selectParameters[0][$i] = $columnParameters;
}
}
if ($this->offset === null) {
$this->offset = 0;
}
// first, produce column list without compound names (using the AS portion only)
array_unshift($sqls, $this->createSqlFromSpecificationAndParameters([
'SELECT %1$s FROM (SELECT b.%1$s, rownum b_rownum FROM (' => current($this->specifications[self::SELECT]),
], $selectParameters));
if ($parameterContainer) {
$number = $this->processInfo['subselectCount'] ? $this->processInfo['subselectCount'] : '';
if ($this->limit === null) {
$sqls[] = ') b ) WHERE b_rownum > (:offset' . $number . ')';
$parameterContainer->offsetSet(
'offset' . $number,
$this->offset,
$parameterContainer::TYPE_INTEGER
);
} else {
// create bottom part of query, with offset and limit using row_number
$sqls[] = ') b WHERE rownum <= (:offset'
. $number
. '+:limit'
. $number
. ')) WHERE b_rownum >= (:offset'
. $number
. ' + 1)';
$parameterContainer->offsetSet(
'offset' . $number,
$this->offset,
$parameterContainer::TYPE_INTEGER
);
$parameterContainer->offsetSet(
'limit' . $number,
$this->limit,
$parameterContainer::TYPE_INTEGER
);
}
$this->processInfo['subselectCount']++;
} else {
if ($this->limit === null) {
$sqls[] = ') b ) WHERE b_rownum > (' . (int) $this->offset . ')';
} else {
$sqls[] = ') b WHERE rownum <= ('
. (int) $this->offset
. '+'
. (int) $this->limit
. ')) WHERE b_rownum >= ('
. (int) $this->offset
. ' + 1)';
}
}
$sqls[self::SELECT] = $this->createSqlFromSpecificationAndParameters(
$this->specifications[self::SELECT],
$parameters[self::SELECT]
);
}
}
================================================
FILE: src/Zend/Db/src/Sql/Platform/Platform.php
================================================
defaultPlatform = $adapter->getPlatform();
$mySqlPlatform = new Mysql\Mysql();
$sqlServerPlatform = new SqlServer\SqlServer();
$oraclePlatform = new Oracle\Oracle();
$ibmDb2Platform = new IbmDb2\IbmDb2();
$sqlitePlatform = new Sqlite\Sqlite();
$this->decorators['mysql'] = $mySqlPlatform->getDecorators();
$this->decorators['sqlserver'] = $sqlServerPlatform->getDecorators();
$this->decorators['oracle'] = $oraclePlatform->getDecorators();
$this->decorators['ibmdb2'] = $ibmDb2Platform->getDecorators();
$this->decorators['sqlite'] = $sqlitePlatform->getDecorators();
}
/**
* @param string $type
* @param PlatformDecoratorInterface $decorator
* @param AdapterInterface|PlatformInterface $adapterOrPlatform
*/
public function setTypeDecorator($type, PlatformDecoratorInterface $decorator, $adapterOrPlatform = null)
{
$platformName = $this->resolvePlatformName($adapterOrPlatform);
$this->decorators[$platformName][$type] = $decorator;
}
/**
* @param PreparableSqlInterface|SqlInterface $subject
* @param AdapterInterface|PlatformInterface|null $adapterOrPlatform
* @return PlatformDecoratorInterface|PreparableSqlInterface|SqlInterface
*/
public function getTypeDecorator($subject, $adapterOrPlatform = null)
{
$platformName = $this->resolvePlatformName($adapterOrPlatform);
if (isset($this->decorators[$platformName])) {
foreach ($this->decorators[$platformName] as $type => $decorator) {
if ($subject instanceof $type && is_a($decorator, $type, true)) {
$decorator->setSubject($subject);
return $decorator;
}
}
}
return $subject;
}
/**
* @return array|PlatformDecoratorInterface[]
*/
public function getDecorators()
{
$platformName = $this->resolvePlatformName($this->getDefaultPlatform());
return $this->decorators[$platformName];
}
/**
* {@inheritDoc}
*
* @throws Exception\RuntimeException
*/
public function prepareStatement(AdapterInterface $adapter, StatementContainerInterface $statementContainer)
{
if (! $this->subject instanceof PreparableSqlInterface) {
throw new Exception\RuntimeException(
'The subject does not appear to implement Zend\Db\Sql\PreparableSqlInterface, thus calling '
. 'prepareStatement() has no effect'
);
}
$this->getTypeDecorator($this->subject, $adapter)->prepareStatement($adapter, $statementContainer);
return $statementContainer;
}
/**
* {@inheritDoc}
*
* @throws Exception\RuntimeException
*/
public function getSqlString(?PlatformInterface $adapterPlatform = null)
{
if (! $this->subject instanceof SqlInterface) {
throw new Exception\RuntimeException(
'The subject does not appear to implement Zend\Db\Sql\SqlInterface, thus calling '
. 'prepareStatement() has no effect'
);
}
$adapterPlatform = $this->resolvePlatform($adapterPlatform);
return $this->getTypeDecorator($this->subject, $adapterPlatform)->getSqlString($adapterPlatform);
}
protected function resolvePlatformName($adapterOrPlatform)
{
$platformName = $this->resolvePlatform($adapterOrPlatform)->getName();
return str_replace([' ', '_'], '', strtolower($platformName));
}
/**
* @param null|PlatformInterface|AdapterInterface $adapterOrPlatform
*
* @return PlatformInterface
*
* @throws Exception\InvalidArgumentException
*/
protected function resolvePlatform($adapterOrPlatform)
{
if (! $adapterOrPlatform) {
return $this->getDefaultPlatform();
}
if ($adapterOrPlatform instanceof AdapterInterface) {
return $adapterOrPlatform->getPlatform();
}
if ($adapterOrPlatform instanceof PlatformInterface) {
return $adapterOrPlatform;
}
throw new Exception\InvalidArgumentException(sprintf(
'$adapterOrPlatform should be null, %s, or %s',
'Zend\Db\Adapter\AdapterInterface',
'Zend\Db\Adapter\Platform\PlatformInterface'
));
}
/**
* @return PlatformInterface
*
* @throws Exception\RuntimeException
*/
protected function getDefaultPlatform()
{
if (! $this->defaultPlatform) {
throw new Exception\RuntimeException('$this->defaultPlatform was not set');
}
return $this->defaultPlatform;
}
}
================================================
FILE: src/Zend/Db/src/Sql/Platform/PlatformDecoratorInterface.php
================================================
subject = $subject;
return $this;
}
/**
* @param PlatformInterface|null $adapterPlatform
* @return array
*/
protected function processTable(?PlatformInterface $adapterPlatform = null)
{
$table = ($this->isTemporary ? '#' : '') . ltrim($this->table, '#');
return [
'',
$adapterPlatform->quoteIdentifier($table),
];
}
}
================================================
FILE: src/Zend/Db/src/Sql/Platform/SqlServer/SelectDecorator.php
================================================
subject = $select;
}
protected function localizeVariables()
{
parent::localizeVariables();
// set specifications
unset($this->specifications[self::LIMIT]);
unset($this->specifications[self::OFFSET]);
$this->specifications['LIMITOFFSET'] = null;
}
/**
* @param PlatformInterface $platform
* @param DriverInterface|null $driver
* @param ParameterContainer|null $parameterContainer
* @param $sqls
* @param $parameters
* @return null
*/
protected function processLimitOffset(
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null,
&$sqls = [],
&$parameters = [],
) {
if ($this->limit === null && $this->offset === null) {
return;
}
$selectParameters = $parameters[self::SELECT];
/** if this is a DISTINCT query then real SELECT part goes to second element in array **/
$parameterIndex = 0;
if ($selectParameters[0] === 'DISTINCT') {
unset($selectParameters[0]);
$selectParameters = array_values($selectParameters);
$parameterIndex = 1;
}
$starSuffix = $platform->getIdentifierSeparator() . self::SQL_STAR;
foreach ($selectParameters[0] as $i => $columnParameters) {
if ($columnParameters[0] == self::SQL_STAR
|| (isset($columnParameters[1]) && $columnParameters[1] == self::SQL_STAR)
|| strpos($columnParameters[0], $starSuffix)
) {
$selectParameters[0] = [[self::SQL_STAR]];
break;
}
if (isset($columnParameters[1])) {
array_shift($columnParameters);
$selectParameters[0][$i] = $columnParameters;
}
}
// first, produce column list without compound names (using the AS portion only)
array_unshift($sqls, $this->createSqlFromSpecificationAndParameters(
['SELECT %1$s FROM (' => current($this->specifications[self::SELECT])],
$selectParameters
));
if ($parameterContainer) {
// create bottom part of query, with offset and limit using row_number
$limitParamName = $driver->formatParameterName('limit');
$offsetParamName = $driver->formatParameterName('offset');
$offsetForSumParamName = $driver->formatParameterName('offsetForSum');
// @codingStandardsIgnoreStart
$sqls[]
= ') AS [ZEND_SQL_SERVER_LIMIT_OFFSET_EMULATION] WHERE [ZEND_SQL_SERVER_LIMIT_OFFSET_EMULATION].[__ZEND_ROW_NUMBER] BETWEEN '
. $offsetParamName . '+1 AND ' . $limitParamName . '+' . $offsetForSumParamName;
// @codingStandardsIgnoreEnd
$parameterContainer->offsetSet('offset', $this->offset);
$parameterContainer->offsetSet('limit', $this->limit);
$parameterContainer->offsetSetReference('offsetForSum', 'offset');
} else {
// @codingStandardsIgnoreStart
$sqls[]
= ') AS [ZEND_SQL_SERVER_LIMIT_OFFSET_EMULATION] WHERE [ZEND_SQL_SERVER_LIMIT_OFFSET_EMULATION].[__ZEND_ROW_NUMBER] BETWEEN '
. (int) $this->offset . '+1 AND '
. (int) $this->limit . '+' . (int) $this->offset;
// @codingStandardsIgnoreEnd
}
if (isset($sqls[self::ORDER])) {
$orderBy = $sqls[self::ORDER];
unset($sqls[self::ORDER]);
} else {
$orderBy = 'ORDER BY (SELECT 1)';
}
// add a column for row_number() using the order specification
$parameters[self::SELECT][$parameterIndex][] = ['ROW_NUMBER() OVER (' . $orderBy . ')', '[__ZEND_ROW_NUMBER]'];
$sqls[self::SELECT] = $this->createSqlFromSpecificationAndParameters(
$this->specifications[self::SELECT],
$parameters[self::SELECT]
);
}
}
================================================
FILE: src/Zend/Db/src/Sql/Platform/SqlServer/SqlServer.php
================================================
setTypeDecorator('Zend\Db\Sql\Select', ($selectDecorator) ?: new SelectDecorator());
$this->setTypeDecorator('Zend\Db\Sql\Ddl\CreateTable', new Ddl\CreateTableDecorator());
}
}
================================================
FILE: src/Zend/Db/src/Sql/Platform/Sqlite/SelectDecorator.php
================================================
subject = $select;
return $this;
}
/**
* {@inheritDoc}
*/
protected function localizeVariables()
{
parent::localizeVariables();
$this->specifications[self::COMBINE] = '%1$s %2$s';
}
/**
* {@inheritDoc}
*/
protected function processStatementStart() {
return '';
}
protected function processLimit(
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
if ($this->limit === null && $this->offset !== null) {
return [''];
}
if ($this->limit === null) {
return;
}
if ($parameterContainer) {
$paramPrefix = $this->processInfo['paramPrefix'];
$parameterContainer->offsetSet($paramPrefix . 'limit', $this->limit, ParameterContainer::TYPE_INTEGER);
return [$driver->formatParameterName('limit')];
}
return [$this->limit];
}
protected function processOffset(
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
if ($this->offset === null) {
return;
}
if ($parameterContainer) {
$paramPrefix = $this->processInfo['paramPrefix'];
$parameterContainer->offsetSet($paramPrefix . 'offset', $this->offset, ParameterContainer::TYPE_INTEGER);
return [$driver->formatParameterName('offset')];
}
return [$this->offset];
}
/**
* {@inheritDoc}
*/
protected function processStatementEnd() {
return '';
}
}
================================================
FILE: src/Zend/Db/src/Sql/Platform/Sqlite/Sqlite.php
================================================
setTypeDecorator('Zend\Db\Sql\Select', new SelectDecorator());
}
}
================================================
FILE: src/Zend/Db/src/Sql/Predicate/Between.php
================================================
setIdentifier($identifier);
}
if ($minValue !== null) {
$this->setMinValue($minValue);
}
if ($maxValue !== null) {
$this->setMaxValue($maxValue);
}
}
/**
* Set identifier for comparison
*
* @param string $identifier
* @return self Provides a fluent interface
*/
public function setIdentifier($identifier)
{
$this->identifier = $identifier;
return $this;
}
/**
* Get identifier of comparison
*
* @return null|string
*/
public function getIdentifier()
{
return $this->identifier;
}
/**
* Set minimum boundary for comparison
*
* @param int|float|string $minValue
* @return self Provides a fluent interface
*/
public function setMinValue($minValue)
{
$this->minValue = $minValue;
return $this;
}
/**
* Get minimum boundary for comparison
*
* @return null|int|float|string
*/
public function getMinValue()
{
return $this->minValue;
}
/**
* Set maximum boundary for comparison
*
* @param int|float|string $maxValue
* @return self Provides a fluent interface
*/
public function setMaxValue($maxValue)
{
$this->maxValue = $maxValue;
return $this;
}
/**
* Get maximum boundary for comparison
*
* @return null|int|float|string
*/
public function getMaxValue()
{
return $this->maxValue;
}
/**
* Set specification string to use in forming SQL predicate
*
* @param string $specification
* @return self Provides a fluent interface
*/
public function setSpecification($specification)
{
$this->specification = $specification;
return $this;
}
/**
* Get specification string to use in forming SQL predicate
*
* @return string
*/
public function getSpecification()
{
return $this->specification;
}
/**
* Return "where" parts
*
* @return array
*/
public function getExpressionData()
{
list($values[], $types[]) = $this->normalizeArgument($this->identifier, self::TYPE_IDENTIFIER);
list($values[], $types[]) = $this->normalizeArgument($this->minValue, self::TYPE_VALUE);
list($values[], $types[]) = $this->normalizeArgument($this->maxValue, self::TYPE_VALUE);
return [
[
$this->getSpecification(),
$values,
$types,
],
];
}
}
================================================
FILE: src/Zend/Db/src/Sql/Predicate/Expression.php
================================================
setExpression($expression);
}
$this->setParameters(is_array($valueParameter) ? $valueParameter : array_slice(func_get_args(), 1));
}
}
================================================
FILE: src/Zend/Db/src/Sql/Predicate/In.php
================================================
setIdentifier($identifier);
}
if ($valueSet !== null) {
$this->setValueSet($valueSet);
}
}
/**
* Set identifier for comparison
*
* @param string|array $identifier
* @return self Provides a fluent interface
*/
public function setIdentifier($identifier)
{
$this->identifier = $identifier;
return $this;
}
/**
* Get identifier of comparison
*
* @return null|string|array
*/
public function getIdentifier()
{
return $this->identifier;
}
/**
* Set set of values for IN comparison
*
* @param array|Select $valueSet
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function setValueSet($valueSet)
{
if (! is_array($valueSet) && ! $valueSet instanceof Select) {
throw new Exception\InvalidArgumentException(
'$valueSet must be either an array or a Zend\Db\Sql\Select object, ' . gettype($valueSet) . ' given'
);
}
$this->valueSet = $valueSet;
return $this;
}
/**
* Gets set of values in IN comparison
*
* @return array|Select
*/
public function getValueSet()
{
return $this->valueSet;
}
/**
* Return array of parts for where statement
*
* @return array
*/
public function getExpressionData()
{
$identifier = $this->getIdentifier();
$values = $this->getValueSet();
$replacements = [];
if (is_array($identifier)) {
$countIdentifier = count($identifier);
$identifierSpecFragment = '(' . implode(', ', array_fill(0, $countIdentifier, '%s')) . ')';
$types = array_fill(0, $countIdentifier, self::TYPE_IDENTIFIER);
$replacements = $identifier;
} else {
$identifierSpecFragment = '%s';
$replacements[] = $identifier;
$types = [self::TYPE_IDENTIFIER];
}
if ($values instanceof Select) {
$specification = vsprintf(
$this->specification,
[$identifierSpecFragment, '%s']
);
$replacements[] = $values;
$types[] = self::TYPE_VALUE;
} else {
foreach ($values as $argument) {
list($replacements[], $types[]) = $this->normalizeArgument($argument, self::TYPE_VALUE);
}
$countValues = count($values);
$valuePlaceholders = $countValues > 0 ? array_fill(0, $countValues, '%s') : [];
$inValueList = implode(', ', $valuePlaceholders);
if ('' === $inValueList) {
$inValueList = 'NULL';
}
$specification = vsprintf(
$this->specification,
[$identifierSpecFragment, '(' . $inValueList . ')']
);
}
return [[
$specification,
$replacements,
$types,
]];
}
}
================================================
FILE: src/Zend/Db/src/Sql/Predicate/IsNotNull.php
================================================
setIdentifier($identifier);
}
}
/**
* Set identifier for comparison
*
* @param string $identifier
* @return self Provides a fluent interface
*/
public function setIdentifier($identifier)
{
$this->identifier = $identifier;
return $this;
}
/**
* Get identifier of comparison
*
* @return null|string
*/
public function getIdentifier()
{
return $this->identifier;
}
/**
* Set specification string to use in forming SQL predicate
*
* @param string $specification
* @return self Provides a fluent interface
*/
public function setSpecification($specification)
{
$this->specification = $specification;
return $this;
}
/**
* Get specification string to use in forming SQL predicate
*
* @return string
*/
public function getSpecification()
{
return $this->specification;
}
/**
* Get parts for where statement
*
* @return array
*/
public function getExpressionData()
{
$identifier = $this->normalizeArgument($this->identifier, self::TYPE_IDENTIFIER);
return [[
$this->getSpecification(),
[$identifier[0]],
[$identifier[1]],
]];
}
}
================================================
FILE: src/Zend/Db/src/Sql/Predicate/Like.php
================================================
setIdentifier($identifier);
}
if ($like) {
$this->setLike($like);
}
}
/**
* @param string $identifier
* @return self Provides a fluent interface
*/
public function setIdentifier($identifier)
{
$this->identifier = $identifier;
return $this;
}
/**
* @return string
*/
public function getIdentifier()
{
return $this->identifier;
}
/**
* @param string $like
* @return self Provides a fluent interface
*/
public function setLike($like)
{
$this->like = $like;
return $this;
}
/**
* @return string
*/
public function getLike()
{
return $this->like;
}
/**
* @param string $specification
* @return self Provides a fluent interface
*/
public function setSpecification($specification)
{
$this->specification = $specification;
return $this;
}
/**
* @return string
*/
public function getSpecification()
{
return $this->specification;
}
/**
* @return array
*/
public function getExpressionData()
{
list($values[], $types[]) = $this->normalizeArgument($this->identifier, self::TYPE_IDENTIFIER);
list($values[], $types[]) = $this->normalizeArgument($this->like, self::TYPE_VALUE);
return [
[
$this->specification,
$values,
$types,
]
];
}
}
================================================
FILE: src/Zend/Db/src/Sql/Predicate/Literal.php
================================================
';
const OP_GT = '>';
const OPERATOR_GREATER_THAN_OR_EQUAL_TO = '>=';
const OP_GTE = '>=';
/**
* {@inheritDoc}
*/
protected $allowedTypes = [
self::TYPE_IDENTIFIER,
self::TYPE_VALUE,
];
/**
* @var int|float|bool|string
*/
protected $left;
/**
* @var int|float|bool|string
*/
protected $right;
/**
* @var string
*/
protected $leftType = self::TYPE_IDENTIFIER;
/**
* @var string
*/
protected $rightType = self::TYPE_VALUE;
/**
* @var string
*/
protected $operator = self::OPERATOR_EQUAL_TO;
/**
* Constructor
*
* @param int|float|bool|string $left
* @param string $operator
* @param int|float|bool|string $right
* @param string $leftType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_IDENTIFIER {@see allowedTypes}
* @param string $rightType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_VALUE {@see allowedTypes}
*/
public function __construct(
$left = null,
$operator = self::OPERATOR_EQUAL_TO,
$right = null,
$leftType = self::TYPE_IDENTIFIER,
$rightType = self::TYPE_VALUE
) {
if ($left !== null) {
$this->setLeft($left);
}
if ($operator !== self::OPERATOR_EQUAL_TO) {
$this->setOperator($operator);
}
if ($right !== null) {
$this->setRight($right);
}
if ($leftType !== self::TYPE_IDENTIFIER) {
$this->setLeftType($leftType);
}
if ($rightType !== self::TYPE_VALUE) {
$this->setRightType($rightType);
}
}
/**
* Set left side of operator
*
* @param int|float|bool|string $left
*
* @return self Provides a fluent interface
*/
public function setLeft($left)
{
$this->left = $left;
if (is_array($left)) {
$left = $this->normalizeArgument($left, $this->leftType);
$this->leftType = $left[1];
}
return $this;
}
/**
* Get left side of operator
*
* @return int|float|bool|string
*/
public function getLeft()
{
return $this->left;
}
/**
* Set parameter type for left side of operator
*
* @param string $type TYPE_IDENTIFIER or TYPE_VALUE {@see allowedTypes}
*
* @return self Provides a fluent interface
*
* @throws Exception\InvalidArgumentException
*/
public function setLeftType($type)
{
if (! in_array($type, $this->allowedTypes)) {
throw new Exception\InvalidArgumentException(sprintf(
'Invalid type "%s" provided; must be of type "%s" or "%s"',
$type,
__CLASS__ . '::TYPE_IDENTIFIER',
__CLASS__ . '::TYPE_VALUE'
));
}
$this->leftType = $type;
return $this;
}
/**
* Get parameter type on left side of operator
*
* @return string
*/
public function getLeftType()
{
return $this->leftType;
}
/**
* Set operator string
*
* @param string $operator
* @return self Provides a fluent interface
*/
public function setOperator($operator)
{
$this->operator = $operator;
return $this;
}
/**
* Get operator string
*
* @return string
*/
public function getOperator()
{
return $this->operator;
}
/**
* Set right side of operator
*
* @param int|float|bool|string $right
*
* @return self Provides a fluent interface
*/
public function setRight($right)
{
$this->right = $right;
if (is_array($right)) {
$right = $this->normalizeArgument($right, $this->rightType);
$this->rightType = $right[1];
}
return $this;
}
/**
* Get right side of operator
*
* @return int|float|bool|string
*/
public function getRight()
{
return $this->right;
}
/**
* Set parameter type for right side of operator
*
* @param string $type TYPE_IDENTIFIER or TYPE_VALUE {@see allowedTypes}
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function setRightType($type)
{
if (! in_array($type, $this->allowedTypes)) {
throw new Exception\InvalidArgumentException(sprintf(
'Invalid type "%s" provided; must be of type "%s" or "%s"',
$type,
__CLASS__ . '::TYPE_IDENTIFIER',
__CLASS__ . '::TYPE_VALUE'
));
}
$this->rightType = $type;
return $this;
}
/**
* Get parameter type on right side of operator
*
* @return string
*/
public function getRightType()
{
return $this->rightType;
}
/**
* Get predicate parts for where statement
*
* @return array
*/
public function getExpressionData()
{
list($values[], $types[]) = $this->normalizeArgument($this->left, $this->leftType);
list($values[], $types[]) = $this->normalizeArgument($this->right, $this->rightType);
return [[
'%s ' . $this->operator . ' %s',
$values,
$types
]];
}
}
================================================
FILE: src/Zend/Db/src/Sql/Predicate/Predicate.php
================================================
setUnnest($this);
$this->addPredicate($predicateSet, ($this->nextPredicateCombineOperator) ?: $this->defaultCombination);
$this->nextPredicateCombineOperator = null;
return $predicateSet;
}
/**
* Indicate what predicate will be unnested
*
* @param Predicate $predicate
* @return void
*/
public function setUnnest(Predicate $predicate)
{
$this->unnest = $predicate;
}
/**
* Indicate end of nested predicate
*
* @return Predicate
* @throws RuntimeException
*/
public function unnest()
{
if ($this->unnest === null) {
throw new RuntimeException('Not nested');
}
$unnest = $this->unnest;
$this->unnest = null;
return $unnest;
}
/**
* Create "Equal To" predicate
*
* Utilizes Operator predicate
*
* @param int|float|bool|string $left
* @param int|float|bool|string $right
* @param string $leftType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_IDENTIFIER {@see allowedTypes}
* @param string $rightType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_VALUE {@see allowedTypes}
* @return self Provides a fluent interface
*/
public function equalTo($left, $right, $leftType = self::TYPE_IDENTIFIER, $rightType = self::TYPE_VALUE)
{
$this->addPredicate(
new Operator($left, Operator::OPERATOR_EQUAL_TO, $right, $leftType, $rightType),
($this->nextPredicateCombineOperator) ?: $this->defaultCombination
);
$this->nextPredicateCombineOperator = null;
return $this;
}
/**
* Create "Not Equal To" predicate
*
* Utilizes Operator predicate
*
* @param int|float|bool|string $left
* @param int|float|bool|string $right
* @param string $leftType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_IDENTIFIER {@see allowedTypes}
* @param string $rightType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_VALUE {@see allowedTypes}
* @return self Provides a fluent interface
*/
public function notEqualTo($left, $right, $leftType = self::TYPE_IDENTIFIER, $rightType = self::TYPE_VALUE)
{
$this->addPredicate(
new Operator($left, Operator::OPERATOR_NOT_EQUAL_TO, $right, $leftType, $rightType),
($this->nextPredicateCombineOperator) ?: $this->defaultCombination
);
$this->nextPredicateCombineOperator = null;
return $this;
}
/**
* Create "Less Than" predicate
*
* Utilizes Operator predicate
*
* @param int|float|bool|string $left
* @param int|float|bool|string $right
* @param string $leftType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_IDENTIFIER {@see allowedTypes}
* @param string $rightType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_VALUE {@see allowedTypes}
* @return self Provides a fluent interface
*/
public function lessThan($left, $right, $leftType = self::TYPE_IDENTIFIER, $rightType = self::TYPE_VALUE)
{
$this->addPredicate(
new Operator($left, Operator::OPERATOR_LESS_THAN, $right, $leftType, $rightType),
($this->nextPredicateCombineOperator) ?: $this->defaultCombination
);
$this->nextPredicateCombineOperator = null;
return $this;
}
/**
* Create "Greater Than" predicate
*
* Utilizes Operator predicate
*
* @param int|float|bool|string $left
* @param int|float|bool|string $right
* @param string $leftType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_IDENTIFIER {@see allowedTypes}
* @param string $rightType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_VALUE {@see allowedTypes}
* @return self Provides a fluent interface
*/
public function greaterThan($left, $right, $leftType = self::TYPE_IDENTIFIER, $rightType = self::TYPE_VALUE)
{
$this->addPredicate(
new Operator($left, Operator::OPERATOR_GREATER_THAN, $right, $leftType, $rightType),
($this->nextPredicateCombineOperator) ?: $this->defaultCombination
);
$this->nextPredicateCombineOperator = null;
return $this;
}
/**
* Create "Less Than Or Equal To" predicate
*
* Utilizes Operator predicate
*
* @param int|float|bool|string $left
* @param int|float|bool|string $right
* @param string $leftType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_IDENTIFIER {@see allowedTypes}
* @param string $rightType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_VALUE {@see allowedTypes}
* @return self Provides a fluent interface
*/
public function lessThanOrEqualTo($left, $right, $leftType = self::TYPE_IDENTIFIER, $rightType = self::TYPE_VALUE)
{
$this->addPredicate(
new Operator($left, Operator::OPERATOR_LESS_THAN_OR_EQUAL_TO, $right, $leftType, $rightType),
($this->nextPredicateCombineOperator) ?: $this->defaultCombination
);
$this->nextPredicateCombineOperator = null;
return $this;
}
/**
* Create "Greater Than Or Equal To" predicate
*
* Utilizes Operator predicate
*
* @param int|float|bool|string $left
* @param int|float|bool|string $right
* @param string $leftType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_IDENTIFIER {@see allowedTypes}
* @param string $rightType TYPE_IDENTIFIER or TYPE_VALUE by default TYPE_VALUE {@see allowedTypes}
* @return self Provides a fluent interface
*/
public function greaterThanOrEqualTo(
$left,
$right,
$leftType = self::TYPE_IDENTIFIER,
$rightType = self::TYPE_VALUE
) {
$this->addPredicate(
new Operator($left, Operator::OPERATOR_GREATER_THAN_OR_EQUAL_TO, $right, $leftType, $rightType),
($this->nextPredicateCombineOperator) ?: $this->defaultCombination
);
$this->nextPredicateCombineOperator = null;
return $this;
}
/**
* Create "Like" predicate
*
* Utilizes Like predicate
*
* @param string|Expression $identifier
* @param string $like
* @return self Provides a fluent interface
*/
public function like($identifier, $like)
{
$this->addPredicate(
new Like($identifier, $like),
($this->nextPredicateCombineOperator) ?: $this->defaultCombination
);
$this->nextPredicateCombineOperator = null;
return $this;
}
/**
* Create "notLike" predicate
*
* Utilizes In predicate
*
* @param string|Expression $identifier
* @param string $notLike
* @return self Provides a fluent interface
*/
public function notLike($identifier, $notLike)
{
$this->addPredicate(
new NotLike($identifier, $notLike),
($this->nextPredicateCombineOperator) ? : $this->defaultCombination
);
$this->nextPredicateCombineOperator = null;
return $this;
}
/**
* Create an expression, with parameter placeholders
*
* @param $expression
* @param $parameters
* @return self Provides a fluent interface
*/
public function expression($expression, $parameters = null)
{
$this->addPredicate(
new Expression($expression, $parameters),
($this->nextPredicateCombineOperator) ?: $this->defaultCombination
);
$this->nextPredicateCombineOperator = null;
return $this;
}
/**
* Create "Literal" predicate
*
* Literal predicate, for parameters, use expression()
*
* @param string $literal
* @return self Provides a fluent interface
*/
public function literal($literal)
{
// process deprecated parameters from previous literal($literal, $parameters = null) signature
if (func_num_args() >= 2) {
$parameters = func_get_arg(1);
$predicate = new Expression($literal, $parameters);
}
// normal workflow for "Literals" here
if (! isset($predicate)) {
$predicate = new Literal($literal);
}
$this->addPredicate(
$predicate,
($this->nextPredicateCombineOperator) ?: $this->defaultCombination
);
$this->nextPredicateCombineOperator = null;
return $this;
}
/**
* Create "IS NULL" predicate
*
* Utilizes IsNull predicate
*
* @param string|Expression $identifier
* @return self Provides a fluent interface
*/
public function isNull($identifier)
{
$this->addPredicate(
new IsNull($identifier),
($this->nextPredicateCombineOperator) ?: $this->defaultCombination
);
$this->nextPredicateCombineOperator = null;
return $this;
}
/**
* Create "IS NOT NULL" predicate
*
* Utilizes IsNotNull predicate
*
* @param string|Expression $identifier
* @return self Provides a fluent interface
*/
public function isNotNull($identifier)
{
$this->addPredicate(
new IsNotNull($identifier),
($this->nextPredicateCombineOperator) ?: $this->defaultCombination
);
$this->nextPredicateCombineOperator = null;
return $this;
}
/**
* Create "IN" predicate
*
* Utilizes In predicate
*
* @param string|Expression $identifier
* @param array|\Zend\Db\Sql\Select $valueSet
* @return self Provides a fluent interface
*/
public function in($identifier, $valueSet = null)
{
$this->addPredicate(
new In($identifier, $valueSet),
($this->nextPredicateCombineOperator) ?: $this->defaultCombination
);
$this->nextPredicateCombineOperator = null;
return $this;
}
/**
* Create "NOT IN" predicate
*
* Utilizes NotIn predicate
*
* @param string|Expression $identifier
* @param array|\Zend\Db\Sql\Select $valueSet
* @return self Provides a fluent interface
*/
public function notIn($identifier, $valueSet = null)
{
$this->addPredicate(
new NotIn($identifier, $valueSet),
($this->nextPredicateCombineOperator) ?: $this->defaultCombination
);
$this->nextPredicateCombineOperator = null;
return $this;
}
/**
* Create "between" predicate
*
* Utilizes Between predicate
*
* @param string|Expression $identifier
* @param int|float|string $minValue
* @param int|float|string $maxValue
* @return self Provides a fluent interface
*/
public function between($identifier, $minValue, $maxValue)
{
$this->addPredicate(
new Between($identifier, $minValue, $maxValue),
($this->nextPredicateCombineOperator) ?: $this->defaultCombination
);
$this->nextPredicateCombineOperator = null;
return $this;
}
/**
* Create "NOT BETWEEN" predicate
*
* Utilizes NotBetween predicate
*
* @param string|Expression $identifier
* @param int|float|string $minValue
* @param int|float|string $maxValue
* @return self Provides a fluent interface
*/
public function notBetween($identifier, $minValue, $maxValue)
{
$this->addPredicate(
new NotBetween($identifier, $minValue, $maxValue),
($this->nextPredicateCombineOperator) ?: $this->defaultCombination
);
$this->nextPredicateCombineOperator = null;
return $this;
}
/**
* Use given predicate directly
*
* Contrary to {@link addPredicate()} this method respects formerly set
* AND / OR combination operator, thus allowing generic predicates to be
* used fluently within where chains as any other concrete predicate.
*
* @param PredicateInterface $predicate
* @return self Provides a fluent interface
*/
public function predicate(PredicateInterface $predicate)
{
$this->addPredicate(
$predicate,
$this->nextPredicateCombineOperator ?: $this->defaultCombination
);
$this->nextPredicateCombineOperator = null;
return $this;
}
/**
* Overloading
*
* Overloads "or", "and", "nest", and "unnest"
*
* @param string $name
* @return self Provides a fluent interface
*/
public function __get($name)
{
switch (strtolower($name)) {
case 'or':
$this->nextPredicateCombineOperator = self::OP_OR;
break;
case 'and':
$this->nextPredicateCombineOperator = self::OP_AND;
break;
case 'nest':
return $this->nest();
case 'unnest':
return $this->unnest();
}
return $this;
}
}
================================================
FILE: src/Zend/Db/src/Sql/Predicate/PredicateInterface.php
================================================
defaultCombination = $defaultCombination;
if ($predicates) {
foreach ($predicates as $predicate) {
$this->addPredicate($predicate);
}
}
}
/**
* Add predicate to set
*
* @param PredicateInterface $predicate
* @param string $combination
* @return self Provides a fluent interface
*/
public function addPredicate(PredicateInterface $predicate, $combination = null)
{
if ($combination === null || ! in_array($combination, [self::OP_AND, self::OP_OR])) {
$combination = $this->defaultCombination;
}
if ($combination == self::OP_OR) {
$this->orPredicate($predicate);
return $this;
}
$this->andPredicate($predicate);
return $this;
}
/**
* Add predicates to set
*
* @param PredicateInterface|\Closure|string|array $predicates
* @param string $combination
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function addPredicates($predicates, $combination = self::OP_AND)
{
if ($predicates === null) {
throw new Exception\InvalidArgumentException('Predicate cannot be null');
}
if ($predicates instanceof PredicateInterface) {
$this->addPredicate($predicates, $combination);
return $this;
}
if ($predicates instanceof \Closure) {
$predicates($this);
return $this;
}
if (is_string($predicates)) {
// String $predicate should be passed as an expression
$predicate = (str_contains($predicates, Expression::PLACEHOLDER))
? new Expression($predicates) : new Literal($predicates);
$this->addPredicate($predicate, $combination);
return $this;
}
if (is_array($predicates)) {
foreach ($predicates as $pkey => $pvalue) {
// loop through predicates
if (is_string($pkey)) {
if (str_contains($pkey, '?')) {
// First, process strings that the abstraction replacement character ?
// as an Expression predicate
$predicate = new Expression($pkey, $pvalue);
} elseif ($pvalue === null) {
// Otherwise, if still a string, do something intelligent with the PHP type provided
// map PHP null to SQL IS NULL expression
$predicate = new IsNull($pkey);
} elseif (is_array($pvalue)) {
// if the value is an array, assume IN() is desired
$predicate = new In($pkey, $pvalue);
} elseif ($pvalue instanceof PredicateInterface) {
throw new Exception\InvalidArgumentException(
'Using Predicate must not use string keys'
);
} else {
// otherwise assume that array('foo' => 'bar') means "foo" = 'bar'
$predicate = new Operator($pkey, Operator::OP_EQ, $pvalue);
}
} elseif ($pvalue instanceof PredicateInterface) {
// Predicate type is ok
$predicate = $pvalue;
} else {
// must be an array of expressions (with int-indexed array)
$predicate = (str_contains($pvalue, Expression::PLACEHOLDER))
? new Expression($pvalue) : new Literal($pvalue);
}
$this->addPredicate($predicate, $combination);
}
}
return $this;
}
/**
* Return the predicates
*
* @return PredicateInterface[]
*/
public function getPredicates()
{
return $this->predicates;
}
/**
* Add predicate using OR operator
*
* @param PredicateInterface $predicate
* @return self Provides a fluent interface
*/
public function orPredicate(PredicateInterface $predicate)
{
$this->predicates[] = [self::OP_OR, $predicate];
return $this;
}
/**
* Add predicate using AND operator
*
* @param PredicateInterface $predicate
* @return self Provides a fluent interface
*/
public function andPredicate(PredicateInterface $predicate)
{
$this->predicates[] = [self::OP_AND, $predicate];
return $this;
}
/**
* Get predicate parts for where statement
*
* @return array
*/
public function getExpressionData()
{
$parts = [];
for ($i = 0, $count = count($this->predicates); $i < $count; $i++) {
/** @var $predicate PredicateInterface */
$predicate = $this->predicates[$i][1];
if ($predicate instanceof PredicateSet) {
$parts[] = '(';
}
$parts = array_merge($parts, $predicate->getExpressionData());
if ($predicate instanceof PredicateSet) {
$parts[] = ')';
}
if (isset($this->predicates[$i + 1])) {
$parts[] = sprintf(' %s ', $this->predicates[$i + 1][0]);
}
}
return $parts;
}
/**
* Get count of attached predicates
*
* @return int
*/
#[ReturnTypeWillChange] public function count()
{
return count($this->predicates);
}
}
================================================
FILE: src/Zend/Db/src/Sql/PreparableSqlInterface.php
================================================
'%1$s',
self::SELECT => [
'SELECT %1$s FROM %2$s' => [
[1 => '%1$s', 2 => '%1$s AS %2$s', 'combinedby' => ', '],
null
],
'SELECT %1$s %2$s FROM %3$s' => [
null,
[1 => '%1$s', 2 => '%1$s AS %2$s', 'combinedby' => ', '],
null
],
'SELECT %1$s' => [
[1 => '%1$s', 2 => '%1$s AS %2$s', 'combinedby' => ', '],
],
],
self::JOINS => [
'%1$s' => [
[3 => '%1$s JOIN %2$s ON %3$s', 'combinedby' => ' ']
]
],
self::WHERE => 'WHERE %1$s',
self::GROUP => [
'GROUP BY %1$s' => [
[1 => '%1$s', 'combinedby' => ', ']
]
],
self::HAVING => 'HAVING %1$s',
self::ORDER => [
'ORDER BY %1$s' => [
[1 => '%1$s', 2 => '%1$s %2$s', 'combinedby' => ', ']
]
],
self::LIMIT => 'LIMIT %1$s',
self::OFFSET => 'OFFSET %1$s',
'statementEnd' => '%1$s',
self::COMBINE => '%1$s ( %2$s )',
];
/**
* @var bool
*/
protected $tableReadOnly = false;
/**
* @var bool
*/
protected $prefixColumnsWithTable = true;
/**
* @var string|array|TableIdentifier
*/
protected $table = null;
/**
* @var null|string|Expression
*/
protected $quantifier = null;
/**
* @var array
*/
protected $columns = [self::SQL_STAR];
/**
* @var null|Join
*/
protected $joins = null;
/**
* @var Where
*/
protected $where = null;
/**
* @var array
*/
protected $order = [];
/**
* @var null|array
*/
protected $group = null;
/**
* @var null|string|array
*/
protected $having = null;
/**
* @var int|null
*/
protected $limit = null;
/**
* @var int|null
*/
protected $offset = null;
/**
* @var array
*/
protected $combine = [];
/**
* Constructor
*
* @param null|string|array|TableIdentifier $table
*/
public function __construct($table = null)
{
if ($table) {
$this->from($table);
$this->tableReadOnly = true;
}
$this->where = new Where;
$this->joins = new Join;
$this->having = new Having;
}
/**
* Create from clause
*
* @param string|array|TableIdentifier $table
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function from($table)
{
if ($this->tableReadOnly) {
throw new Exception\InvalidArgumentException(
'Since this object was created with a table and/or schema in the constructor, it is read only.'
);
}
if (! is_string($table) && ! is_array($table) && ! $table instanceof TableIdentifier) {
throw new Exception\InvalidArgumentException(
'$table must be a string, array, or an instance of TableIdentifier'
);
}
if (is_array($table) && (! is_string(key($table)) || count($table) !== 1)) {
throw new Exception\InvalidArgumentException(
'from() expects $table as an array is a single element associative array'
);
}
$this->table = $table;
return $this;
}
/**
* @param string|Expression $quantifier DISTINCT|ALL
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function quantifier($quantifier)
{
if (! is_string($quantifier) && ! $quantifier instanceof ExpressionInterface) {
throw new Exception\InvalidArgumentException(
'Quantifier must be one of DISTINCT, ALL, or some platform specific object implementing '
. 'ExpressionInterface'
);
}
$this->quantifier = $quantifier;
return $this;
}
/**
* Specify columns from which to select
*
* Possible valid states:
*
* array(*)
*
* array(value, ...)
* value can be strings or Expression objects
*
* array(string => value, ...)
* key string will be use as alias,
* value can be string or Expression objects
*
* @param array $columns
* @param bool $prefixColumnsWithTable
* @return self Provides a fluent interface
*/
public function columns(array $columns, $prefixColumnsWithTable = true)
{
$this->columns = $columns;
$this->prefixColumnsWithTable = (bool) $prefixColumnsWithTable;
return $this;
}
/**
* Create join clause
*
* @param string|array|TableIdentifier $name
* @param string|Predicate\Expression $on
* @param string|array $columns
* @param string $type one of the JOIN_* constants
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function join($name, $on, $columns = self::SQL_STAR, $type = self::JOIN_INNER)
{
$this->joins->join($name, $on, $columns, $type);
return $this;
}
/**
* Create where clause
*
* @param Where|\Closure|string|array|Predicate\PredicateInterface $predicate
* @param string $combination One of the OP_* constants from Predicate\PredicateSet
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function where($predicate, $combination = Predicate\PredicateSet::OP_AND)
{
if ($predicate instanceof Where) {
$this->where = $predicate;
} else {
$this->where->addPredicates($predicate, $combination);
}
return $this;
}
/**
* @param mixed $group
* @return self Provides a fluent interface
*/
public function group($group)
{
if (is_array($group)) {
foreach ($group as $o) {
$this->group[] = $o;
}
} else {
$this->group[] = $group;
}
return $this;
}
/**
* Create having clause
*
* @param Where|\Closure|string|array $predicate
* @param string $combination One of the OP_* constants from Predicate\PredicateSet
* @return self Provides a fluent interface
*/
public function having($predicate, $combination = Predicate\PredicateSet::OP_AND)
{
if ($predicate instanceof Having) {
$this->having = $predicate;
} else {
$this->having->addPredicates($predicate, $combination);
}
return $this;
}
/**
* @param string|array|Expression $order
* @return self Provides a fluent interface
*/
public function order($order)
{
if (is_string($order)) {
if (str_contains($order, ',')) {
$order = preg_split('#,\s+#', $order);
} else {
$order = (array) $order;
}
} elseif (! is_array($order)) {
$order = [$order];
}
foreach ($order as $k => $v) {
if (is_string($k)) {
$this->order[$k] = $v;
} else {
$this->order[] = $v;
}
}
return $this;
}
/**
* @param int $limit
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function limit($limit)
{
if (! is_numeric($limit)) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects parameter to be numeric, "%s" given',
__METHOD__,
(is_object($limit) ? get_class($limit) : gettype($limit))
));
}
$this->limit = $limit;
return $this;
}
/**
* @param int $offset
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function offset($offset)
{
if (! is_numeric($offset)) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects parameter to be numeric, "%s" given',
__METHOD__,
(is_object($offset) ? get_class($offset) : gettype($offset))
));
}
$this->offset = $offset;
return $this;
}
/**
* @param Select $select
* @param string $type
* @param string $modifier
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function combine(Select $select, $type = self::COMBINE_UNION, $modifier = '')
{
if ($this->combine !== []) {
throw new Exception\InvalidArgumentException(
'This Select object is already combined and cannot be combined with multiple Selects objects'
);
}
$this->combine = [
'select' => $select,
'type' => $type,
'modifier' => $modifier
];
return $this;
}
/**
* @param string $part
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function reset($part)
{
switch ($part) {
case self::TABLE:
if ($this->tableReadOnly) {
throw new Exception\InvalidArgumentException(
'Since this object was created with a table and/or schema in the constructor, it is read only.'
);
}
$this->table = null;
break;
case self::QUANTIFIER:
$this->quantifier = null;
break;
case self::COLUMNS:
$this->columns = [];
break;
case self::JOINS:
$this->joins = new Join;
break;
case self::WHERE:
$this->where = new Where;
break;
case self::GROUP:
$this->group = null;
break;
case self::HAVING:
$this->having = new Having;
break;
case self::LIMIT:
$this->limit = null;
break;
case self::OFFSET:
$this->offset = null;
break;
case self::ORDER:
$this->order = [];
break;
case self::COMBINE:
$this->combine = [];
break;
}
return $this;
}
/**
* @param $index
* @param $specification
* @return self Provides a fluent interface
*/
public function setSpecification($index, $specification)
{
if (! method_exists($this, 'process' . $index)) {
throw new Exception\InvalidArgumentException('Not a valid specification name.');
}
$this->specifications[$index] = $specification;
return $this;
}
public function getRawState($key = null)
{
$rawState = [
self::TABLE => $this->table,
self::QUANTIFIER => $this->quantifier,
self::COLUMNS => $this->columns,
self::JOINS => $this->joins,
self::WHERE => $this->where,
self::ORDER => $this->order,
self::GROUP => $this->group,
self::HAVING => $this->having,
self::LIMIT => $this->limit,
self::OFFSET => $this->offset,
self::COMBINE => $this->combine
];
return (isset($key) && array_key_exists($key, $rawState)) ? $rawState[$key] : $rawState;
}
/**
* Returns whether the table is read only or not.
*
* @return bool
*/
public function isTableReadOnly()
{
return $this->tableReadOnly;
}
protected function processStatementStart() {
if ($this->combine !== []) {
return ['('];
}
}
protected function processStatementEnd() {
if ($this->combine !== []) {
return [')'];
}
}
/**
* Process the select part
*
* @param PlatformInterface $platform
* @param DriverInterface|null $driver
* @param ParameterContainer|null $parameterContainer
* @return null|array
*/
protected function processSelect(
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
$expr = 1;
[$table, $fromTable] = $this->resolveTable($this->table, $platform, $driver, $parameterContainer);
// process table columns
$columns = [];
foreach ($this->columns as $columnIndexOrAs => $column) {
if ($column === self::SQL_STAR) {
$columns[] = [$fromTable . self::SQL_STAR];
continue;
}
$columnName = $this->resolveColumnValue(
[
'column' => $column,
'fromTable' => $fromTable,
'isIdentifier' => true,
],
$platform,
$driver,
$parameterContainer,
(is_string($columnIndexOrAs) ? $columnIndexOrAs : 'column')
);
// process As portion
if (is_string($columnIndexOrAs)) {
$columnAs = $platform->quoteIdentifier($columnIndexOrAs);
} elseif (stripos($columnName, ' as ') === false) {
$columnAs = (is_string($column)) ? $platform->quoteIdentifier($column) : 'Expression' . $expr++;
}
$columns[] = (isset($columnAs)) ? [$columnName, $columnAs] : [$columnName];
}
// process join columns
foreach ($this->joins->getJoins() as $join) {
$joinName = (is_array($join['name'])) ? key($join['name']) : $join['name'];
$joinName = parent::resolveTable($joinName, $platform, $driver, $parameterContainer);
foreach ($join['columns'] as $jKey => $jColumn) {
$jColumns = [];
$jFromTable = is_scalar($jColumn)
? $joinName . $platform->getIdentifierSeparator()
: '';
$jColumns[] = $this->resolveColumnValue(
[
'column' => $jColumn,
'fromTable' => $jFromTable,
'isIdentifier' => true,
],
$platform,
$driver,
$parameterContainer,
(is_string($jKey) ? $jKey : 'column')
);
if (is_string($jKey)) {
$jColumns[] = $platform->quoteIdentifier($jKey);
} elseif ($jColumn !== self::SQL_STAR) {
$jColumns[] = $platform->quoteIdentifier($jColumn);
}
$columns[] = $jColumns;
}
}
if ($this->quantifier) {
$quantifier = ($this->quantifier instanceof ExpressionInterface)
? $this->processExpression($this->quantifier, $platform, $driver, $parameterContainer, 'quantifier')
: $this->quantifier;
}
if (! isset($table)) {
return [$columns];
} elseif (isset($quantifier)) {
return [$quantifier, $columns, $table];
} else {
return [$columns, $table];
}
}
protected function processJoins(
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
return $this->processJoin($this->joins, $platform, $driver, $parameterContainer);
}
protected function processWhere(
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
if ($this->where->count() == 0) {
return;
}
return [
$this->processExpression($this->where, $platform, $driver, $parameterContainer, 'where')
];
}
protected function processGroup(
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
if ($this->group === null) {
return;
}
// process table columns
$groups = [];
foreach ($this->group as $column) {
$groups[] = $this->resolveColumnValue(
[
'column' => $column,
'isIdentifier' => true,
],
$platform,
$driver,
$parameterContainer,
'group'
);
}
return [$groups];
}
protected function processHaving(
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
if ($this->having->count() == 0) {
return;
}
return [
$this->processExpression($this->having, $platform, $driver, $parameterContainer, 'having')
];
}
protected function processOrder(
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
if (empty($this->order)) {
return;
}
$orders = [];
foreach ($this->order as $k => $v) {
if ($v instanceof ExpressionInterface) {
$orders[] = [
$this->processExpression($v, $platform, $driver, $parameterContainer)
];
continue;
}
if (is_int($k)) {
if (str_contains($v, ' ')) {
[$k, $v] = explode(' ', $v, 2);
} else {
$k = $v;
$v = self::ORDER_ASCENDING;
}
}
if (strcasecmp(trim($v), self::ORDER_DESCENDING) === 0) {
$orders[] = [$platform->quoteIdentifierInFragment($k), self::ORDER_DESCENDING];
} else {
$orders[] = [$platform->quoteIdentifierInFragment($k), self::ORDER_ASCENDING];
}
}
return [$orders];
}
protected function processLimit(
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
if ($this->limit === null) {
return;
}
if ($parameterContainer) {
$paramPrefix = $this->processInfo['paramPrefix'];
$parameterContainer->offsetSet($paramPrefix . 'limit', $this->limit, ParameterContainer::TYPE_INTEGER);
return [$driver->formatParameterName($paramPrefix . 'limit')];
}
return [$platform->quoteValue($this->limit)];
}
protected function processOffset(
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
if ($this->offset === null) {
return;
}
if ($parameterContainer) {
$paramPrefix = $this->processInfo['paramPrefix'];
$parameterContainer->offsetSet($paramPrefix . 'offset', $this->offset, ParameterContainer::TYPE_INTEGER);
return [$driver->formatParameterName($paramPrefix . 'offset')];
}
return [$platform->quoteValue($this->offset)];
}
protected function processCombine(
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
if ($this->combine == []) {
return;
}
$type = $this->combine['type'];
if ($this->combine['modifier']) {
$type .= ' ' . $this->combine['modifier'];
}
return [
strtoupper($type),
$this->processSubSelect($this->combine['select'], $platform, $driver, $parameterContainer),
];
}
/**
* Variable overloading
*
* @param string $name
* @throws Exception\InvalidArgumentException
* @return mixed
*/
public function __get($name)
{
switch (strtolower($name)) {
case 'where':
return $this->where;
case 'having':
return $this->having;
case 'joins':
return $this->joins;
default:
throw new Exception\InvalidArgumentException('Not a valid magic property for this object');
}
}
/**
* __clone
*
* Resets the where object each time the Select is cloned.
*
* @return void
*/
public function __clone()
{
$this->where = clone $this->where;
$this->joins = clone $this->joins;
$this->having = clone $this->having;
}
/**
* @param string|TableIdentifier|Select $table
* @param PlatformInterface $platform
* @param DriverInterface|null $driver
* @param ParameterContainer|null $parameterContainer
* @return string
*/
protected function resolveTable(
$table,
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
$alias = null;
if (is_array($table)) {
$alias = key($table);
$table = current($table);
}
$table = parent::resolveTable($table, $platform, $driver, $parameterContainer);
if ($alias) {
$fromTable = $platform->quoteIdentifier($alias);
$table = $this->renderTable($table, $fromTable);
} else {
$fromTable = $table;
}
if ($this->prefixColumnsWithTable && $fromTable) {
$fromTable .= $platform->getIdentifierSeparator();
} else {
$fromTable = '';
}
return [
$table,
$fromTable
];
}
}
================================================
FILE: src/Zend/Db/src/Sql/Sql.php
================================================
adapter = $adapter;
if ($table) {
$this->setTable($table);
}
$this->sqlPlatform = $sqlPlatform ?: new Platform\Platform($adapter);
}
/**
* @return null|\Zend\Db\Adapter\AdapterInterface
*/
public function getAdapter()
{
return $this->adapter;
}
public function hasTable()
{
return ($this->table !== null);
}
/**
* @param string|array|TableIdentifier $table
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function setTable($table)
{
if (is_string($table) || is_array($table) || $table instanceof TableIdentifier) {
$this->table = $table;
} else {
throw new Exception\InvalidArgumentException(
'Table must be a string, array or instance of TableIdentifier.'
);
}
return $this;
}
public function getTable()
{
return $this->table;
}
public function getSqlPlatform()
{
return $this->sqlPlatform;
}
public function select($table = null)
{
if ($this->table !== null && $table !== null) {
throw new Exception\InvalidArgumentException(sprintf(
'This Sql object is intended to work with only the table "%s" provided at construction time.',
$this->table
));
}
return new Select(($table) ?: $this->table);
}
public function insert($table = null)
{
if ($this->table !== null && $table !== null) {
throw new Exception\InvalidArgumentException(sprintf(
'This Sql object is intended to work with only the table "%s" provided at construction time.',
$this->table
));
}
return new Insert(($table) ?: $this->table);
}
public function update($table = null)
{
if ($this->table !== null && $table !== null) {
throw new Exception\InvalidArgumentException(sprintf(
'This Sql object is intended to work with only the table "%s" provided at construction time.',
$this->table
));
}
return new Update(($table) ?: $this->table);
}
public function delete($table = null)
{
if ($this->table !== null && $table !== null) {
throw new Exception\InvalidArgumentException(sprintf(
'This Sql object is intended to work with only the table "%s" provided at construction time.',
$this->table
));
}
return new Delete(($table) ?: $this->table);
}
/**
* @param PreparableSqlInterface $sqlObject
* @param StatementInterface|null $statement
* @param AdapterInterface|null $adapter
*
* @return StatementInterface
*/
public function prepareStatementForSqlObject(
PreparableSqlInterface $sqlObject,
?StatementInterface $statement = null,
?AdapterInterface $adapter = null
) {
$adapter = $adapter ?: $this->adapter;
$statement = $statement ?: $adapter->getDriver()->createStatement();
return $this->sqlPlatform->setSubject($sqlObject)->prepareStatement($adapter, $statement);
}
/**
* Get sql string using platform or sql object
*
* @param SqlInterface $sqlObject
* @param PlatformInterface|null $platform
*
* @return string
*
* @deprecated Deprecated in 2.4. Use buildSqlString() instead
*/
public function getSqlStringForSqlObject(SqlInterface $sqlObject, ?PlatformInterface $platform = null)
{
$platform = ($platform) ?: $this->adapter->getPlatform();
return $this->sqlPlatform->setSubject($sqlObject)->getSqlString($platform);
}
/**
* @param SqlInterface $sqlObject
* @param AdapterInterface|null $adapter
*
* @return string
*
* @throws Exception\InvalidArgumentException
*/
public function buildSqlString(SqlInterface $sqlObject, ?AdapterInterface $adapter = null)
{
return $this
->sqlPlatform
->setSubject($sqlObject)
->getSqlString($adapter ? $adapter->getPlatform() : $this->adapter->getPlatform());
}
}
================================================
FILE: src/Zend/Db/src/Sql/SqlInterface.php
================================================
table = (string) $table;
if ('' === $this->table) {
throw new Exception\InvalidArgumentException('$table must be a valid table name, empty string given');
}
if (null === $schema) {
$this->schema = null;
} else {
if (! (is_string($schema) || is_callable([$schema, '__toString']))) {
throw new Exception\InvalidArgumentException(sprintf(
'$schema must be a valid schema name, parameter of type %s given',
is_object($schema) ? get_class($schema) : gettype($schema)
));
}
$this->schema = (string) $schema;
if ('' === $this->schema) {
throw new Exception\InvalidArgumentException(
'$schema must be a valid schema name or null, empty string given'
);
}
}
}
/**
* @param string $table
*
* @deprecated please use the constructor and build a new {@see TableIdentifier} instead
*/
public function setTable($table)
{
$this->table = $table;
}
/**
* @return string
*/
public function getTable()
{
return $this->table;
}
/**
* @return bool
*/
public function hasSchema()
{
return ($this->schema !== null);
}
/**
* @param $schema
*
* @deprecated please use the constructor and build a new {@see TableIdentifier} instead
*/
public function setSchema($schema)
{
$this->schema = $schema;
}
/**
* @return null|string
*/
public function getSchema()
{
return $this->schema;
}
public function getTableAndSchema()
{
return [$this->table, $this->schema];
}
}
================================================
FILE: src/Zend/Db/src/Sql/Update.php
================================================
'UPDATE %1$s',
self::SPECIFICATION_JOIN => [
'%1$s' => [
[3 => '%1$s JOIN %2$s ON %3$s', 'combinedby' => ' ']
]
],
self::SPECIFICATION_SET => 'SET %1$s',
self::SPECIFICATION_WHERE => 'WHERE %1$s',
];
/**
* @var string|TableIdentifier
*/
protected $table = '';
/**
* @var bool
*/
protected $emptyWhereProtection = true;
/**
* @var PriorityList
*/
protected $set;
/**
* @var string|Where
*/
protected $where = null;
/**
* @var null|Join
*/
protected $joins = null;
/**
* Constructor
*
* @param null|string|TableIdentifier $table
*/
public function __construct($table = null)
{
if ($table) {
$this->table($table);
}
$this->where = new Where();
$this->joins = new Join();
$this->set = new PriorityList();
$this->set->isLIFO(false);
}
/**
* Specify table for statement
*
* @param string|TableIdentifier $table
* @return self Provides a fluent interface
*/
public function table($table)
{
$this->table = $table;
return $this;
}
/**
* Set key/value pairs to update
*
* @param array $values Associative array of key values
* @param string $flag One of the VALUES_* constants
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function set(array $values, $flag = self::VALUES_SET)
{
if ($values === null) {
throw new Exception\InvalidArgumentException('set() expects an array of values');
}
if ($flag == self::VALUES_SET) {
$this->set->clear();
}
$priority = is_numeric($flag) ? $flag : 0;
foreach ($values as $k => $v) {
if (! is_string($k)) {
throw new Exception\InvalidArgumentException('set() expects a string for the value key');
}
$this->set->insert($k, $v, $priority);
}
return $this;
}
/**
* Create where clause
*
* @param Where|\Closure|string|array $predicate
* @param string $combination One of the OP_* constants from Predicate\PredicateSet
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function where($predicate, $combination = Predicate\PredicateSet::OP_AND)
{
if ($predicate instanceof Where) {
$this->where = $predicate;
} else {
$this->where->addPredicates($predicate, $combination);
}
return $this;
}
/**
* Create join clause
*
* @param string|array $name
* @param string $on
* @param string $type one of the JOIN_* constants
* @return self Provides a fluent interface
* @throws Exception\InvalidArgumentException
*/
public function join($name, $on, $type = Join::JOIN_INNER)
{
$this->joins->join($name, $on, [], $type);
return $this;
}
public function getRawState($key = null)
{
$rawState = [
'emptyWhereProtection' => $this->emptyWhereProtection,
'table' => $this->table,
'set' => $this->set->toArray(),
'where' => $this->where,
'joins' => $this->joins
];
return (isset($key) && array_key_exists($key, $rawState)) ? $rawState[$key] : $rawState;
}
protected function processUpdate(
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
return sprintf(
$this->specifications[static::SPECIFICATION_UPDATE],
$this->resolveTable($this->table, $platform, $driver, $parameterContainer)
);
}
protected function processSet(
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
$setSql = [];
$i = 0;
foreach ($this->set as $column => $value) {
$prefix = $this->resolveColumnValue(
[
'column' => $column,
'fromTable' => '',
'isIdentifier' => true,
],
$platform,
$driver,
$parameterContainer,
'column'
);
$prefix .= ' = ';
if (is_scalar($value) && $parameterContainer) {
// use incremental value instead of column name for PDO
// @see https://github.com/zendframework/zend-db/issues/35
if ($driver instanceof Pdo) {
$column = 'c_' . $i++;
}
$setSql[] = $prefix . $driver->formatParameterName($column);
$parameterContainer->offsetSet($column, $value);
} else {
$setSql[] = $prefix . $this->resolveColumnValue(
$value,
$platform,
$driver,
$parameterContainer
);
}
}
return sprintf(
$this->specifications[static::SPECIFICATION_SET],
implode(', ', $setSql)
);
}
protected function processWhere(
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
if ($this->where->count() == 0) {
return;
}
return sprintf(
$this->specifications[static::SPECIFICATION_WHERE],
$this->processExpression($this->where, $platform, $driver, $parameterContainer, 'where')
);
}
protected function processJoins(
PlatformInterface $platform,
?DriverInterface $driver = null,
?ParameterContainer $parameterContainer = null
) {
return $this->processJoin($this->joins, $platform, $driver, $parameterContainer);
}
/**
* Variable overloading
*
* Proxies to "where" only
*
* @param string $name
* @return mixed
*/
public function __get($name)
{
if (strtolower($name) == 'where') {
return $this->where;
}
}
/**
* __clone
*
* Resets the where object each time the Update is cloned.
*
* @return void
*/
public function __clone()
{
$this->where = clone $this->where;
$this->set = clone $this->set;
}
}
================================================
FILE: src/Zend/Db/src/Sql/Where.php
================================================
isInitialized;
}
/**
* Initialize
*
* @throws Exception\RuntimeException
* @return null
*/
public function initialize()
{
if ($this->isInitialized) {
return;
}
if (! $this->featureSet instanceof Feature\FeatureSet) {
$this->featureSet = new Feature\FeatureSet;
}
$this->featureSet->setTableGateway($this);
$this->featureSet->apply(EventFeatureEventsInterface::EVENT_PRE_INITIALIZE, []);
if (! $this->adapter instanceof AdapterInterface) {
throw new Exception\RuntimeException('This table does not have an Adapter setup');
}
if (! is_string($this->table) && ! $this->table instanceof TableIdentifier && ! is_array($this->table)) {
throw new Exception\RuntimeException('This table object does not have a valid table set.');
}
if (! $this->resultSetPrototype instanceof ResultSetInterface) {
$this->resultSetPrototype = new ResultSet;
}
if (! $this->sql instanceof Sql) {
$this->sql = new Sql($this->adapter, $this->table);
}
$this->featureSet->apply(EventFeatureEventsInterface::EVENT_POST_INITIALIZE, []);
$this->isInitialized = true;
}
/**
* Get table name
*
* @return string
*/
public function getTable()
{
return $this->table;
}
/**
* Get adapter
*
* @return AdapterInterface
*/
public function getAdapter()
{
return $this->adapter;
}
/**
* @return array
*/
public function getColumns()
{
return $this->columns;
}
/**
* @return Feature\FeatureSet
*/
public function getFeatureSet()
{
return $this->featureSet;
}
/**
* Get select result prototype
*
* @return ResultSetInterface
*/
public function getResultSetPrototype()
{
return $this->resultSetPrototype;
}
/**
* @return Sql
*/
public function getSql()
{
return $this->sql;
}
/**
* Select
*
* @param Where|\Closure|string|array $where
* @return ResultSetInterface
*/
public function select($where = null)
{
if (! $this->isInitialized) {
$this->initialize();
}
$select = $this->sql->select();
if ($where instanceof \Closure) {
$where($select);
} elseif ($where !== null) {
$select->where($where);
}
return $this->selectWith($select);
}
/**
* @param Select $select
* @return ResultSetInterface
*/
public function selectWith(Select $select)
{
if (! $this->isInitialized) {
$this->initialize();
}
return $this->executeSelect($select);
}
/**
* @param Select $select
* @return ResultSetInterface
* @throws Exception\RuntimeException
*/
protected function executeSelect(Select $select)
{
$selectState = $select->getRawState();
if (isset($selectState['table'])
&& $selectState['table'] != $this->table
&& (is_array($selectState['table'])
&& end($selectState['table']) != $this->table)
) {
throw new Exception\RuntimeException(
'The table name of the provided Select object must match that of the table'
);
}
if (isset($selectState['columns'])
&& $selectState['columns'] == [Select::SQL_STAR]
&& $this->columns !== []) {
$select->columns($this->columns);
}
// apply preSelect features
$this->featureSet->apply(EventFeatureEventsInterface::EVENT_PRE_SELECT, [$select]);
// prepare and execute
$statement = $this->sql->prepareStatementForSqlObject($select);
$result = $statement->execute();
// build result set
$resultSet = clone $this->resultSetPrototype;
$resultSet->initialize($result);
// apply postSelect features
$this->featureSet->apply(EventFeatureEventsInterface::EVENT_POST_SELECT, [$statement, $result, $resultSet]);
return $resultSet;
}
/**
* Insert
*
* @param array $set
* @return int
*/
public function insert($set)
{
if (! $this->isInitialized) {
$this->initialize();
}
$insert = $this->sql->insert();
$insert->values($set);
return $this->executeInsert($insert);
}
/**
* @param Insert $insert
* @return int
*/
public function insertWith(Insert $insert)
{
if (! $this->isInitialized) {
$this->initialize();
}
return $this->executeInsert($insert);
}
/**
* @todo add $columns support
*
* @param Insert $insert
* @return int
* @throws Exception\RuntimeException
*/
protected function executeInsert(Insert $insert)
{
$insertState = $insert->getRawState();
if ($insertState['table'] != $this->table) {
throw new Exception\RuntimeException(
'The table name of the provided Insert object must match that of the table'
);
}
// apply preInsert features
$this->featureSet->apply(EventFeatureEventsInterface::EVENT_PRE_INSERT, [$insert]);
// Most RDBMS solutions do not allow using table aliases in INSERTs
// See https://github.com/zendframework/zf2/issues/7311
$unaliasedTable = false;
if (is_array($insertState['table'])) {
$tableData = array_values($insertState['table']);
$unaliasedTable = array_shift($tableData);
$insert->into($unaliasedTable);
}
$statement = $this->sql->prepareStatementForSqlObject($insert);
$result = $statement->execute();
$this->lastInsertValue = $this->adapter->getDriver()->getConnection()->getLastGeneratedValue();
// apply postInsert features
$this->featureSet->apply(EventFeatureEventsInterface::EVENT_POST_INSERT, [$statement, $result]);
// Reset original table information in Insert instance, if necessary
if ($unaliasedTable) {
$insert->into($insertState['table']);
}
return $result->getAffectedRows();
}
/**
* Update
*
* @param array $set
* @param string|array|\Closure $where
* @param array|null $joins
* @return int
*/
public function update($set, $where = null, ?array $joins = null)
{
if (! $this->isInitialized) {
$this->initialize();
}
$sql = $this->sql;
$update = $sql->update();
$update->set($set);
if ($where !== null) {
$update->where($where);
}
if ($joins) {
foreach ($joins as $join) {
$type = $join['type'] ?? Join::JOIN_INNER;
$update->join($join['name'], $join['on'], $type);
}
}
return $this->executeUpdate($update);
}
/**
* @param \Zend\Db\Sql\Update $update
* @return int
*/
public function updateWith(Update $update)
{
if (! $this->isInitialized) {
$this->initialize();
}
return $this->executeUpdate($update);
}
/**
* @todo add $columns support
*
* @param Update $update
* @return int
* @throws Exception\RuntimeException
*/
protected function executeUpdate(Update $update)
{
$updateState = $update->getRawState();
if ($updateState['table'] != $this->table) {
throw new Exception\RuntimeException(
'The table name of the provided Update object must match that of the table'
);
}
// apply preUpdate features
$this->featureSet->apply(EventFeatureEventsInterface::EVENT_PRE_UPDATE, [$update]);
$unaliasedTable = false;
if (is_array($updateState['table'])) {
$tableData = array_values($updateState['table']);
$unaliasedTable = array_shift($tableData);
$update->table($unaliasedTable);
}
$statement = $this->sql->prepareStatementForSqlObject($update);
$result = $statement->execute();
// apply postUpdate features
$this->featureSet->apply(EventFeatureEventsInterface::EVENT_POST_UPDATE, [$statement, $result]);
// Reset original table information in Update instance, if necessary
if ($unaliasedTable) {
$update->table($updateState['table']);
}
return $result->getAffectedRows();
}
/**
* Delete
*
* @param Where|\Closure|string|array $where
* @return int
*/
public function delete($where)
{
if (! $this->isInitialized) {
$this->initialize();
}
$delete = $this->sql->delete();
if ($where instanceof \Closure) {
$where($delete);
} else {
$delete->where($where);
}
return $this->executeDelete($delete);
}
/**
* @param Delete $delete
* @return int
*/
public function deleteWith(Delete $delete)
{
$this->initialize();
return $this->executeDelete($delete);
}
/**
* @todo add $columns support
*
* @param Delete $delete
* @return int
* @throws Exception\RuntimeException
*/
protected function executeDelete(Delete $delete)
{
$deleteState = $delete->getRawState();
if ($deleteState['table'] != $this->table) {
throw new Exception\RuntimeException(
'The table name of the provided Delete object must match that of the table'
);
}
// pre delete update
$this->featureSet->apply(EventFeatureEventsInterface::EVENT_PRE_DELETE, [$delete]);
$unaliasedTable = false;
if (is_array($deleteState['table'])) {
$tableData = array_values($deleteState['table']);
$unaliasedTable = array_shift($tableData);
$delete->from($unaliasedTable);
}
$statement = $this->sql->prepareStatementForSqlObject($delete);
$result = $statement->execute();
// apply postDelete features
$this->featureSet->apply(EventFeatureEventsInterface::EVENT_POST_DELETE, [$statement, $result]);
// Reset original table information in Delete instance, if necessary
if ($unaliasedTable) {
$delete->from($deleteState['table']);
}
return $result->getAffectedRows();
}
/**
* Get last insert value
*
* @return int
*/
public function getLastInsertValue()
{
return $this->lastInsertValue;
}
/**
* __get
*
* @param string $property
* @throws Exception\InvalidArgumentException
* @return mixed
*/
public function __get($property)
{
switch (strtolower($property)) {
case 'lastinsertvalue':
return $this->lastInsertValue;
case 'adapter':
return $this->adapter;
case 'table':
return $this->table;
}
if ($this->featureSet->canCallMagicGet()) {
return $this->featureSet->callMagicGet();
}
throw new Exception\InvalidArgumentException('Invalid magic property access in ' . __CLASS__ . '::__get()');
}
/**
* @param string $property
* @param mixed $value
* @return mixed
* @throws Exception\InvalidArgumentException
*/
public function __set($property, $value)
{
if ($this->featureSet->canCallMagicSet()) {
return $this->featureSet->callMagicSet();
}
throw new Exception\InvalidArgumentException('Invalid magic property access in ' . __CLASS__ . '::__set()');
}
/**
* @param $method
* @param $arguments
* @return mixed
* @throws Exception\InvalidArgumentException
*/
public function __call($method, $arguments)
{
if ($this->featureSet->canCallMagicCall($method)) {
return $this->featureSet->callMagicCall($method, $arguments);
}
throw new Exception\InvalidArgumentException(sprintf(
'Invalid method (%s) called, caught by %s::__call()',
$method,
__CLASS__
));
}
/**
* __clone
*/
public function __clone()
{
$this->resultSetPrototype = (isset($this->resultSetPrototype)) ? clone $this->resultSetPrototype : null;
$this->sql = clone $this->sql;
if (is_object($this->table)) {
$this->table = clone $this->table;
} elseif (is_array($this->table)
&& count($this->table) == 1
&& is_object(reset($this->table))
) {
foreach ($this->table as &$tableObject) {
$tableObject = clone $tableObject;
}
}
}
}
================================================
FILE: src/Zend/Db/src/TableGateway/Exception/ExceptionInterface.php
================================================
tableGateway = $tableGateway;
}
public function initialize()
{
throw new Exception\RuntimeException('This method is not intended to be called on this object.');
}
public function getMagicMethodSpecifications()
{
return [];
}
/*
public function preInitialize();
public function postInitialize();
public function preSelect(Select $select);
public function postSelect(StatementInterface $statement, ResultInterface $result, ResultSetInterface $resultSet);
public function preInsert(Insert $insert);
public function postInsert(StatementInterface $statement, ResultInterface $result);
public function preUpdate(Update $update);
public function postUpdate(StatementInterface $statement, ResultInterface $result);
public function preDelete(Delete $delete);
public function postDelete(StatementInterface $statement, ResultInterface $result);
*/
}
================================================
FILE: src/Zend/Db/src/TableGateway/Feature/EventFeature/TableGatewayEvent.php
================================================
name;
}
/**
* Get target/context from which event was triggered
*
* @return null|string|object
*/
public function getTarget()
{
return $this->target;
}
/**
* Get parameters passed to the event
*
* @return array|\ArrayAccess
*/
public function getParams()
{
return $this->params;
}
/**
* Get a single parameter by name
*
* @param string $name
* @param mixed $default Default value to return if parameter does not exist
* @return mixed
*/
public function getParam($name, $default = null)
{
return (isset($this->params[$name]) ? $this->params[$name] : $default);
}
/**
* Set the event name
*
* @param string $name
* @return void
*/
public function setName($name)
{
$this->name = $name;
}
/**
* Set the event target/context
*
* @param null|string|object $target
* @return void
*/
public function setTarget($target)
{
$this->target = $target;
}
/**
* Set event parameters
*
* @param string $params
* @return void
*/
public function setParams($params)
{
$this->params = $params;
}
/**
* Set a single parameter by key
*
* @param string $name
* @param mixed $value
* @return void
*/
public function setParam($name, $value)
{
$this->params[$name] = $value;
}
/**
* Indicate whether or not the parent EventManagerInterface should stop propagating events
*
* @param bool $flag
* @return void
*/
public function stopPropagation($flag = true)
{
return;
}
/**
* Has this event indicated event propagation should stop?
*
* @return bool
*/
public function propagationIsStopped()
{
return false;
}
}
================================================
FILE: src/Zend/Db/src/TableGateway/Feature/EventFeature.php
================================================
eventManager = ($eventManager instanceof EventManagerInterface)
? $eventManager
: new EventManager;
$this->eventManager->addIdentifiers([
'Zend\Db\TableGateway\TableGateway',
]);
$this->event = ($tableGatewayEvent) ?: new EventFeature\TableGatewayEvent();
}
/**
* Retrieve composed event manager instance
*
* @return EventManagerInterface
*/
public function getEventManager()
{
return $this->eventManager;
}
/**
* Retrieve composed event instance
*
* @return EventFeature\TableGatewayEvent
*/
public function getEvent()
{
return $this->event;
}
/**
* Initialize feature and trigger "preInitialize" event
*
* Ensures that the composed TableGateway has identifiers based on the
* class name, and that the event target is set to the TableGateway
* instance. It then triggers the "preInitialize" event.
*
* @return void
*/
public function preInitialize()
{
if (get_class($this->tableGateway) != 'Zend\Db\TableGateway\TableGateway') {
$this->eventManager->addIdentifiers([get_class($this->tableGateway)]);
}
$this->event->setTarget($this->tableGateway);
$this->event->setName(static::EVENT_PRE_INITIALIZE);
$this->eventManager->triggerEvent($this->event);
}
/**
* Trigger the "postInitialize" event
*
* @return void
*/
public function postInitialize()
{
$this->event->setName(static::EVENT_POST_INITIALIZE);
$this->eventManager->triggerEvent($this->event);
}
/**
* Trigger the "preSelect" event
*
* Triggers the "preSelect" event mapping the following parameters:
* - $select as "select"
*
* @param Select $select
* @return void
*/
public function preSelect(Select $select)
{
$this->event->setName(static::EVENT_PRE_SELECT);
$this->event->setParams(['select' => $select]);
$this->eventManager->triggerEvent($this->event);
}
/**
* Trigger the "postSelect" event
*
* Triggers the "postSelect" event mapping the following parameters:
* - $statement as "statement"
* - $result as "result"
* - $resultSet as "result_set"
*
* @param StatementInterface $statement
* @param ResultInterface $result
* @param ResultSetInterface $resultSet
* @return void
*/
public function postSelect(StatementInterface $statement, ResultInterface $result, ResultSetInterface $resultSet)
{
$this->event->setName(static::EVENT_POST_SELECT);
$this->event->setParams([
'statement' => $statement,
'result' => $result,
'result_set' => $resultSet
]);
$this->eventManager->triggerEvent($this->event);
}
/**
* Trigger the "preInsert" event
*
* Triggers the "preInsert" event mapping the following parameters:
* - $insert as "insert"
*
* @param Insert $insert
* @return void
*/
public function preInsert(Insert $insert)
{
$this->event->setName(static::EVENT_PRE_INSERT);
$this->event->setParams(['insert' => $insert]);
$this->eventManager->triggerEvent($this->event);
}
/**
* Trigger the "postInsert" event
*
* Triggers the "postInsert" event mapping the following parameters:
* - $statement as "statement"
* - $result as "result"
*
* @param StatementInterface $statement
* @param ResultInterface $result
* @return void
*/
public function postInsert(StatementInterface $statement, ResultInterface $result)
{
$this->event->setName(static::EVENT_POST_INSERT);
$this->event->setParams([
'statement' => $statement,
'result' => $result,
]);
$this->eventManager->triggerEvent($this->event);
}
/**
* Trigger the "preUpdate" event
*
* Triggers the "preUpdate" event mapping the following parameters:
* - $update as "update"
*
* @param Update $update
* @return void
*/
public function preUpdate(Update $update)
{
$this->event->setName(static::EVENT_PRE_UPDATE);
$this->event->setParams(['update' => $update]);
$this->eventManager->triggerEvent($this->event);
}
/**
* Trigger the "postUpdate" event
*
* Triggers the "postUpdate" event mapping the following parameters:
* - $statement as "statement"
* - $result as "result"
*
* @param StatementInterface $statement
* @param ResultInterface $result
* @return void
*/
public function postUpdate(StatementInterface $statement, ResultInterface $result)
{
$this->event->setName(static::EVENT_POST_UPDATE);
$this->event->setParams([
'statement' => $statement,
'result' => $result,
]);
$this->eventManager->triggerEvent($this->event);
}
/**
* Trigger the "preDelete" event
*
* Triggers the "preDelete" event mapping the following parameters:
* - $delete as "delete"
*
* @param Delete $delete
* @return void
*/
public function preDelete(Delete $delete)
{
$this->event->setName(static::EVENT_PRE_DELETE);
$this->event->setParams(['delete' => $delete]);
$this->eventManager->triggerEvent($this->event);
}
/**
* Trigger the "postDelete" event
*
* Triggers the "postDelete" event mapping the following parameters:
* - $statement as "statement"
* - $result as "result"
*
* @param StatementInterface $statement
* @param ResultInterface $result
* @return void
*/
public function postDelete(StatementInterface $statement, ResultInterface $result)
{
$this->event->setName(static::EVENT_POST_DELETE);
$this->event->setParams([
'statement' => $statement,
'result' => $result,
]);
$this->eventManager->triggerEvent($this->event);
}
}
================================================
FILE: src/Zend/Db/src/TableGateway/Feature/EventFeatureEventsInterface.php
================================================
addFeatures($features);
}
}
/**
* @param AbstractTableGateway $tableGateway
* @return self Provides a fluent interface
*/
public function setTableGateway(AbstractTableGateway $tableGateway)
{
$this->tableGateway = $tableGateway;
foreach ($this->features as $feature) {
$feature->setTableGateway($this->tableGateway);
}
return $this;
}
public function getFeatureByClassName($featureClassName)
{
$feature = false;
foreach ($this->features as $potentialFeature) {
if ($potentialFeature instanceof $featureClassName) {
$feature = $potentialFeature;
break;
}
}
return $feature;
}
/**
* @param array $features
* @return self Provides a fluent interface
*/
public function addFeatures(array $features)
{
foreach ($features as $feature) {
$this->addFeature($feature);
}
return $this;
}
/**
* @param AbstractFeature $feature
* @return self Provides a fluent interface
*/
public function addFeature(AbstractFeature $feature)
{
if ($this->tableGateway instanceof TableGatewayInterface) {
$feature->setTableGateway($this->tableGateway);
}
$this->features[] = $feature;
return $this;
}
public function apply($method, $args)
{
foreach ($this->features as $feature) {
if (method_exists($feature, $method)) {
$return = call_user_func_array([$feature, $method], $args);
if ($return === self::APPLY_HALT) {
break;
}
}
}
}
/**
* @return bool
*/
public function canCallMagicGet()
{
return false;
}
/**
* @return mixed
*/
public function callMagicGet()
{
$return = null;
return $return;
}
/**
* @return bool
*/
public function canCallMagicSet()
{
return false;
}
/**
* @return mixed
*/
public function callMagicSet()
{
$return = null;
return $return;
}
/**
* Is the method requested available in one of the added features
* @param string $method
* @return bool
*/
public function canCallMagicCall($method)
{
if (! empty($this->features)) {
foreach ($this->features as $feature) {
if (method_exists($feature, $method)) {
return true;
}
}
}
return false;
}
/**
* Call method of on added feature as though it were a local method
* @param string $method
* @param array $arguments
* @return mixed
*/
public function callMagicCall($method, $arguments)
{
foreach ($this->features as $feature) {
if (method_exists($feature, $method)) {
return $feature->$method($arguments);
}
}
return;
}
}
================================================
FILE: src/Zend/Db/src/TableGateway/Feature/GlobalAdapterFeature.php
================================================
tableGateway->adapter = self::getStaticAdapter();
}
}
================================================
FILE: src/Zend/Db/src/TableGateway/Feature/MasterSlaveFeature.php
================================================
slaveAdapter = $slaveAdapter;
if ($slaveSql) {
$this->slaveSql = $slaveSql;
}
}
public function getSlaveAdapter()
{
return $this->slaveAdapter;
}
/**
* @return Sql
*/
public function getSlaveSql()
{
return $this->slaveSql;
}
/**
* after initialization, retrieve the original adapter as "master"
*/
public function postInitialize()
{
$this->masterSql = $this->tableGateway->sql;
if ($this->slaveSql === null) {
$this->slaveSql = new Sql(
$this->slaveAdapter,
$this->tableGateway->sql->getTable(),
$this->tableGateway->sql->getSqlPlatform()
);
}
}
/**
* preSelect()
* Replace adapter with slave temporarily
*/
public function preSelect()
{
$this->tableGateway->sql = $this->slaveSql;
}
/**
* postSelect()
* Ensure to return to the master adapter
*/
public function postSelect()
{
$this->tableGateway->sql = $this->masterSql;
}
}
================================================
FILE: src/Zend/Db/src/TableGateway/Feature/MetadataFeature.php
================================================
metadata = $metadata;
}
$this->sharedData['metadata'] = [
'primaryKey' => null,
'columns' => []
];
}
public function postInitialize()
{
if ($this->metadata === null) {
$this->metadata = SourceFactory::createSourceFromAdapter($this->tableGateway->adapter);
}
// localize variable for brevity
$t = $this->tableGateway;
$m = $this->metadata;
$tableGatewayTable = is_array($t->table) ? current($t->table) : $t->table;
if ($tableGatewayTable instanceof TableIdentifier) {
$table = $tableGatewayTable->getTable();
$schema = $tableGatewayTable->getSchema();
} else {
$table = $tableGatewayTable;
$schema = null;
}
// get column named
$columns = $m->getColumnNames($table, $schema);
$t->columns = $columns;
// set locally
$this->sharedData['metadata']['columns'] = $columns;
// process primary key only if table is a table; there are no PK constraints on views
if (! ($m->getTable($table, $schema) instanceof TableObject)) {
return;
}
$pkc = null;
foreach ($m->getConstraints($table, $schema) as $constraint) {
/** @var $constraint \Zend\Db\Metadata\Object\ConstraintObject */
if ($constraint->getType() == 'PRIMARY KEY') {
$pkc = $constraint;
break;
}
}
if ($pkc === null) {
throw new Exception\RuntimeException('A primary key for this column could not be found in the metadata.');
}
$pkcColumns = $pkc->getColumns();
if (count($pkcColumns) === 1) {
$primaryKey = $pkcColumns[0];
} else {
$primaryKey = $pkcColumns;
}
$this->sharedData['metadata']['primaryKey'] = $primaryKey;
}
}
================================================
FILE: src/Zend/Db/src/TableGateway/Feature/RowGatewayFeature.php
================================================
constructorArguments = func_get_args();
}
public function postInitialize()
{
$args = $this->constructorArguments;
/** @var $resultSetPrototype ResultSet */
$resultSetPrototype = $this->tableGateway->resultSetPrototype;
if (! $this->tableGateway->resultSetPrototype instanceof ResultSet) {
throw new Exception\RuntimeException(
'This feature ' . __CLASS__ . ' expects the ResultSet to be an instance of Zend\Db\ResultSet\ResultSet'
);
}
if (isset($args[0])) {
if (is_string($args[0])) {
$primaryKey = $args[0];
$rowGatewayPrototype = new RowGateway(
$primaryKey,
$this->tableGateway->table,
$this->tableGateway->adapter
);
$resultSetPrototype->setArrayObjectPrototype($rowGatewayPrototype);
} elseif ($args[0] instanceof RowGatewayInterface) {
$rowGatewayPrototype = $args[0];
$resultSetPrototype->setArrayObjectPrototype($rowGatewayPrototype);
}
} else {
// get from metadata feature
$metadata = $this->tableGateway->featureSet->getFeatureByClassName(
'Zend\Db\TableGateway\Feature\MetadataFeature'
);
if ($metadata === false || ! isset($metadata->sharedData['metadata'])) {
throw new Exception\RuntimeException(
'No information was provided to the RowGatewayFeature and/or no MetadataFeature could be consulted '
. 'to find the primary key necessary for RowGateway object creation.'
);
}
$primaryKey = $metadata->sharedData['metadata']['primaryKey'];
$rowGatewayPrototype = new RowGateway(
$primaryKey,
$this->tableGateway->table,
$this->tableGateway->adapter
);
$resultSetPrototype->setArrayObjectPrototype($rowGatewayPrototype);
}
}
}
================================================
FILE: src/Zend/Db/src/TableGateway/Feature/SequenceFeature.php
================================================
primaryKeyField = $primaryKeyField;
$this->sequenceName = $sequenceName;
}
/**
* @param Insert $insert
* @return Insert
*/
public function preInsert(Insert $insert)
{
$this->tableGateway->lastInsertValue = $this->lastSequenceId();
$columns = $insert->getRawState('columns');
$values = $insert->getRawState('values');
$key = array_search($this->primaryKeyField, $columns);
if ($key !== false) {
$this->sequenceValue = $values[$key];
return $insert;
}
$this->sequenceValue = $this->nextSequenceId();
if ($this->sequenceValue === null) {
return $insert;
}
$insert->values([$this->primaryKeyField => $this->sequenceValue], Insert::VALUES_MERGE);
return $insert;
}
/**
*/
public function postInsert()
{
$this->tableGateway->lastInsertValue = $this->sequenceValue;
}
/**
* Generate a new value from the specified sequence in the database, and return it.
* @return int
*/
public function nextSequenceId()
{
$platform = $this->tableGateway->adapter->getPlatform();
$platformName = $platform->getName();
switch ($platformName) {
case 'Oracle':
$sql = 'SELECT ' . $platform->quoteIdentifier($this->sequenceName) . '.NEXTVAL as "nextval" FROM dual';
break;
case 'PostgreSQL':
$sql = 'SELECT NEXTVAL(\'"' . $this->sequenceName . '"\')';
break;
default:
return;
}
$statement = $this->tableGateway->adapter->createStatement();
$statement->prepare($sql);
$result = $statement->execute();
$sequence = $result->current();
unset($statement, $result);
return $sequence['nextval'];
}
/**
* Return the most recent value from the specified sequence in the database.
* @return int
*/
public function lastSequenceId()
{
$platform = $this->tableGateway->adapter->getPlatform();
$platformName = $platform->getName();
switch ($platformName) {
case 'Oracle':
$sql = 'SELECT ' . $platform->quoteIdentifier($this->sequenceName) . '.CURRVAL as "currval" FROM dual';
break;
case 'PostgreSQL':
$sql = 'SELECT CURRVAL(\'' . $this->sequenceName . '\')';
break;
default:
return;
}
$statement = $this->tableGateway->adapter->createStatement();
$statement->prepare($sql);
$result = $statement->execute();
$sequence = $result->current();
unset($statement, $result);
return $sequence['currval'];
}
}
================================================
FILE: src/Zend/Db/src/TableGateway/TableGateway.php
================================================
table = $table;
// adapter
$this->adapter = $adapter;
// process features
if ($features !== null) {
if ($features instanceof Feature\AbstractFeature) {
$features = [$features];
}
if (is_array($features)) {
$this->featureSet = new Feature\FeatureSet($features);
} elseif ($features instanceof Feature\FeatureSet) {
$this->featureSet = $features;
} else {
throw new Exception\InvalidArgumentException(
'TableGateway expects $feature to be an instance of an AbstractFeature or a FeatureSet, or an '
. 'array of AbstractFeatures'
);
}
} else {
$this->featureSet = new Feature\FeatureSet();
}
// result prototype
$this->resultSetPrototype = ($resultSetPrototype) ?: new ResultSet;
// Sql object (factory for select, insert, update, delete)
$this->sql = ($sql) ?: new Sql($this->adapter, $this->table);
// check sql object bound to same table
if ($this->sql->getTable() != $this->table) {
throw new Exception\InvalidArgumentException(
'The table inside the provided Sql object must match the table of this TableGateway'
);
}
$this->initialize();
}
}
================================================
FILE: src/Zend/Db/src/TableGateway/TableGatewayInterface.php
================================================
'quot', // quotation mark
38 => 'amp', // ampersand
60 => 'lt', // less-than sign
62 => 'gt', // greater-than sign
];
/**
* Current encoding for escaping. If not UTF-8, we convert strings from this encoding
* pre-escaping and back to this encoding post-escaping.
*
* @var string
*/
protected $encoding = 'utf-8';
/**
* Holds the value of the special flags passed as second parameter to
* htmlspecialchars().
*
* @var int
*/
protected $htmlSpecialCharsFlags;
/**
* Static Matcher which escapes characters for HTML Attribute contexts
*
* @var callable
*/
protected $htmlAttrMatcher;
/**
* Static Matcher which escapes characters for Javascript contexts
*
* @var callable
*/
protected $jsMatcher;
/**
* Static Matcher which escapes characters for CSS Attribute contexts
*
* @var callable
*/
protected $cssMatcher;
/**
* List of all encoding supported by this class
*
* @var array
*/
protected $supportedEncodings = [
'iso-8859-1', 'iso8859-1', 'iso-8859-5', 'iso8859-5',
'iso-8859-15', 'iso8859-15', 'utf-8', 'cp866',
'ibm866', '866', 'cp1251', 'windows-1251',
'win-1251', '1251', 'cp1252', 'windows-1252',
'1252', 'koi8-r', 'koi8-ru', 'koi8r',
'big5', '950', 'gb2312', '936',
'big5-hkscs', 'shift_jis', 'sjis', 'sjis-win',
'cp932', '932', 'euc-jp', 'eucjp',
'eucjp-win', 'macroman'
];
/**
* Constructor: Single parameter allows setting of global encoding for use by
* the current object.
*
* @param string $encoding
* @throws Exception\InvalidArgumentException
*/
public function __construct($encoding = null)
{
if ($encoding !== null) {
if (! is_string($encoding)) {
throw new Exception\InvalidArgumentException(
get_class($this) . ' constructor parameter must be a string, received ' . gettype($encoding)
);
}
if ($encoding === '') {
throw new Exception\InvalidArgumentException(
get_class($this) . ' constructor parameter does not allow a blank value'
);
}
$encoding = strtolower($encoding);
if (! in_array($encoding, $this->supportedEncodings)) {
throw new Exception\InvalidArgumentException(
'Value of \'' . $encoding . '\' passed to ' . get_class($this)
. ' constructor parameter is invalid. Provide an encoding supported by htmlspecialchars()'
);
}
$this->encoding = $encoding;
}
// We take advantage of ENT_SUBSTITUTE flag to correctly deal with invalid UTF-8 sequences.
$this->htmlSpecialCharsFlags = ENT_QUOTES | ENT_SUBSTITUTE;
// set matcher callbacks
$this->htmlAttrMatcher = [$this, 'htmlAttrMatcher'];
$this->jsMatcher = [$this, 'jsMatcher'];
$this->cssMatcher = [$this, 'cssMatcher'];
}
/**
* Return the encoding that all output/input is expected to be encoded in.
*
* @return string
*/
public function getEncoding()
{
return $this->encoding;
}
/**
* Escape a string for the HTML Body context where there are very few characters
* of special meaning. Internally this will use htmlspecialchars().
*
* @param string $string
* @return string
*/
public function escapeHtml($string)
{
return htmlspecialchars($string, $this->htmlSpecialCharsFlags, $this->encoding);
}
/**
* Escape a string for the HTML Attribute context. We use an extended set of characters
* to escape that are not covered by htmlspecialchars() to cover cases where an attribute
* might be unquoted or quoted illegally (e.g. backticks are valid quotes for IE).
*
* @param string $string
* @return string
*/
public function escapeHtmlAttr($string)
{
$string = $this->toUtf8($string);
if ($string === '' || ctype_digit($string)) {
return $string;
}
$result = preg_replace_callback('/[^a-z0-9,\.\-_]/iSu', $this->htmlAttrMatcher, $string);
return $this->fromUtf8($result);
}
/**
* Escape a string for the Javascript context. This does not use json_encode(). An extended
* set of characters are escaped beyond ECMAScript's rules for Javascript literal string
* escaping in order to prevent misinterpretation of Javascript as HTML leading to the
* injection of special characters and entities. The escaping used should be tolerant
* of cases where HTML escaping was not applied on top of Javascript escaping correctly.
* Backslash escaping is not used as it still leaves the escaped character as-is and so
* is not useful in a HTML context.
*
* @param string $string
* @return string
*/
public function escapeJs($string)
{
$string = $this->toUtf8($string);
if ($string === '' || ctype_digit($string)) {
return $string;
}
$result = preg_replace_callback('/[^a-z0-9,\._]/iSu', $this->jsMatcher, $string);
return $this->fromUtf8($result);
}
/**
* Escape a string for the URI or Parameter contexts. This should not be used to escape
* an entire URI - only a subcomponent being inserted. The function is a simple proxy
* to rawurlencode() which now implements RFC 3986 since PHP 5.3 completely.
*
* @param string $string
* @return string
*/
public function escapeUrl($string)
{
return rawurlencode($string);
}
/**
* Escape a string for the CSS context. CSS escaping can be applied to any string being
* inserted into CSS and escapes everything except alphanumerics.
*
* @param string $string
* @return string
*/
public function escapeCss($string)
{
$string = $this->toUtf8($string);
if ($string === '' || ctype_digit($string)) {
return $string;
}
$result = preg_replace_callback('/[^a-z0-9]/iSu', $this->cssMatcher, $string);
return $this->fromUtf8($result);
}
/**
* Callback function for preg_replace_callback that applies HTML Attribute
* escaping to all matches.
*
* @param array $matches
* @return string
*/
protected function htmlAttrMatcher($matches)
{
$chr = $matches[0];
$ord = ord($chr);
/**
* The following replaces characters undefined in HTML with the
* hex entity for the Unicode replacement character.
*/
if (($ord <= 0x1f && $chr != "\t" && $chr != "\n" && $chr != "\r")
|| ($ord >= 0x7f && $ord <= 0x9f)
) {
return '�';
}
/**
* Check if the current character to escape has a name entity we should
* replace it with while grabbing the integer value of the character.
*/
if (strlen($chr) > 1) {
$chr = $this->convertEncoding($chr, 'UTF-32BE', 'UTF-8');
}
$hex = bin2hex($chr);
$ord = hexdec($hex);
if (isset(static::$htmlNamedEntityMap[$ord])) {
return '&' . static::$htmlNamedEntityMap[$ord] . ';';
}
/**
* Per OWASP recommendations, we'll use upper hex entities
* for any other characters where a named entity does not exist.
*/
if ($ord > 255) {
return sprintf('%04X;', $ord);
}
return sprintf('%02X;', $ord);
}
/**
* Callback function for preg_replace_callback that applies Javascript
* escaping to all matches.
*
* @param array $matches
* @return string
*/
protected function jsMatcher($matches)
{
$chr = $matches[0];
if (strlen($chr) == 1) {
return sprintf('\\x%02X', ord($chr));
}
$chr = $this->convertEncoding($chr, 'UTF-16BE', 'UTF-8');
$hex = strtoupper(bin2hex($chr));
if (strlen($hex) <= 4) {
return sprintf('\\u%04s', $hex);
}
$highSurrogate = substr($hex, 0, 4);
$lowSurrogate = substr($hex, 4, 4);
return sprintf('\\u%04s\\u%04s', $highSurrogate, $lowSurrogate);
}
/**
* Callback function for preg_replace_callback that applies CSS
* escaping to all matches.
*
* @param array $matches
* @return string
*/
protected function cssMatcher($matches)
{
$chr = $matches[0];
if (strlen($chr) == 1) {
$ord = ord($chr);
} else {
$chr = $this->convertEncoding($chr, 'UTF-32BE', 'UTF-8');
$ord = hexdec(bin2hex($chr));
}
return sprintf('\\%X ', $ord);
}
/**
* Converts a string to UTF-8 from the base encoding. The base encoding is set via this
* class' constructor.
*
* @param string $string
* @throws Exception\RuntimeException
* @return string
*/
protected function toUtf8($string)
{
if ($this->getEncoding() === 'utf-8') {
$result = $string;
} else {
$result = $this->convertEncoding($string, 'UTF-8', $this->getEncoding());
}
if (! $this->isUtf8($result)) {
throw new Exception\RuntimeException(
sprintf('String to be escaped was not valid UTF-8 or could not be converted: %s', $result)
);
}
return $result;
}
/**
* Converts a string from UTF-8 to the base encoding. The base encoding is set via this
* class' constructor.
* @param string $string
* @return string
*/
protected function fromUtf8($string)
{
if ($this->getEncoding() === 'utf-8') {
return $string;
}
return $this->convertEncoding($string, $this->getEncoding(), 'UTF-8');
}
/**
* Checks if a given string appears to be valid UTF-8 or not.
*
* @param string $string
* @return bool
*/
protected function isUtf8($string)
{
return ($string === '' || preg_match('/^./su', $string));
}
/**
* Encoding conversion helper which wraps iconv and mbstring where they exist or throws
* and exception where neither is available.
*
* @param string $string
* @param string $to
* @param array|string $from
* @throws Exception\RuntimeException
* @return string
*/
protected function convertEncoding($string, $to, $from)
{
if (function_exists('iconv')) {
$result = iconv($from, $to, $string);
} elseif (function_exists('mb_convert_encoding')) {
$result = mb_convert_encoding($string, $to, $from);
} else {
throw new Exception\RuntimeException(
get_class($this)
. ' requires either the iconv or mbstring extension to be installed'
. ' when escaping for non UTF-8 strings.'
);
}
if ($result === false) {
return ''; // return non-fatal blank string on encoding errors from users
}
return $result;
}
}
================================================
FILE: src/Zend/Escaper/src/Exception/ExceptionInterface.php
================================================
listeners as $index => $callback) {
if ($events->detach($callback)) {
unset($this->listeners[$index]);
}
}
}
}
================================================
FILE: src/Zend/EventManager/src/Event.php
================================================
setName($name);
}
if (null !== $target) {
$this->setTarget($target);
}
if (null !== $params) {
$this->setParams($params);
}
}
/**
* Get event name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Get the event target
*
* This may be either an object, or the name of a static method.
*
* @return string|object
*/
public function getTarget()
{
return $this->target;
}
/**
* Set parameters
*
* Overwrites parameters
*
* @param array|ArrayAccess|object $params
* @return Event
* @throws Exception\InvalidArgumentException
*/
public function setParams($params)
{
if (!is_array($params) && !is_object($params)) {
throw new Exception\InvalidArgumentException(
sprintf('Event parameters must be an array or object; received "%s"', gettype($params))
);
}
$this->params = $params;
return $this;
}
/**
* Get all parameters
*
* @return array|object|ArrayAccess
*/
public function getParams()
{
return $this->params;
}
/**
* Get an individual parameter
*
* If the parameter does not exist, the $default value will be returned.
*
* @param string|int $name
* @param mixed $default
* @return mixed
*/
public function getParam($name, $default = null)
{
// Check in params that are arrays or implement array access
if (is_array($this->params) || $this->params instanceof ArrayAccess) {
if (!isset($this->params[$name])) {
return $default;
}
return $this->params[$name];
}
// Check in normal objects
if (!isset($this->params->{$name})) {
return $default;
}
return $this->params->{$name};
}
/**
* Set the event name
*
* @param string $name
* @return Event
*/
public function setName($name)
{
$this->name = (string) $name;
return $this;
}
/**
* Set the event target/context
*
* @param null|string|object $target
* @return Event
*/
public function setTarget($target)
{
$this->target = $target;
return $this;
}
/**
* Set an individual parameter to a value
*
* @param string|int $name
* @param mixed $value
* @return Event
*/
public function setParam($name, $value)
{
if (is_array($this->params) || $this->params instanceof ArrayAccess) {
// Arrays or objects implementing array access
$this->params[$name] = $value;
} else {
// Objects
$this->params->{$name} = $value;
}
return $this;
}
/**
* Stop further event propagation
*
* @param bool $flag
* @return void
*/
public function stopPropagation($flag = true)
{
$this->stopPropagation = (bool) $flag;
}
/**
* Is propagation stopped?
*
* @return bool
*/
public function propagationIsStopped()
{
return $this->stopPropagation;
}
}
================================================
FILE: src/Zend/EventManager/src/EventInterface.php
================================================
setIdentifiers($identifiers);
}
/**
* Set the event class to utilize
*
* @deprecated This method is deprecated with 2.6.0, and will be removed in 3.0.0.
* See {@link https://github.com/zendframework/zend-eventmanager/blob/develop/doc/book/migration/removed.md}
* for details.
* @param string $class
* @return EventManager
*/
public function setEventClass($class)
{
$this->eventClass = $class;
return $this;
}
/**
* Set shared event manager
*
* @deprecated This method is deprecated with 2.6.0, and will be removed in 3.0.0.
* See {@link https://github.com/zendframework/zend-eventmanager/blob/develop/doc/book/migration/removed.md}
* for details.
* @param SharedEventManagerInterface $sharedEventManager
* @return EventManager
*/
public function setSharedManager(SharedEventManagerInterface $sharedEventManager)
{
$this->sharedManager = $sharedEventManager;
StaticEventManager::setInstance($sharedEventManager);
return $this;
}
/**
* Remove any shared event manager currently attached
*
* @deprecated This method is deprecated with 2.6.0, and will be removed in 3.0.0.
* See {@link https://github.com/zendframework/zend-eventmanager/blob/develop/doc/book/migration/removed.md}
* for details.
* @return void
*/
public function unsetSharedManager()
{
$this->sharedManager = false;
}
/**
* Get shared event manager
*
* If one is not defined, but we have a static instance in
* StaticEventManager, that one will be used and set in this instance.
*
* If none is available in the StaticEventManager, a boolean false is
* returned.
*
* @return false|SharedEventManagerInterface
*/
public function getSharedManager()
{
// "false" means "I do not want a shared manager; don't try and fetch one"
if (false === $this->sharedManager
|| $this->sharedManager instanceof SharedEventManagerInterface
) {
return $this->sharedManager;
}
if (!StaticEventManager::hasInstance()) {
return false;
}
$this->sharedManager = StaticEventManager::getInstance();
return $this->sharedManager;
}
/**
* Get the identifier(s) for this EventManager
*
* @return array
*/
public function getIdentifiers()
{
return $this->identifiers;
}
/**
* Set the identifiers (overrides any currently set identifiers)
*
* @param string|int|array|Traversable $identifiers
* @return EventManager Provides a fluent interface
*/
public function setIdentifiers($identifiers)
{
if (is_array($identifiers) || $identifiers instanceof Traversable) {
$this->identifiers = array_unique((array) $identifiers);
} elseif ($identifiers !== null) {
$this->identifiers = [$identifiers];
}
return $this;
}
/**
* Add some identifier(s) (appends to any currently set identifiers)
*
* @param string|int|array|Traversable $identifiers
* @return EventManager Provides a fluent interface
*/
public function addIdentifiers($identifiers)
{
if (is_array($identifiers) || $identifiers instanceof Traversable) {
$this->identifiers = array_unique(array_merge($this->identifiers, (array) $identifiers));
} elseif ($identifiers !== null) {
$this->identifiers = array_unique(array_merge($this->identifiers, [$identifiers]));
}
return $this;
}
/**
* Trigger all listeners for a given event
*
* @param string|EventInterface $event
* @param string|object $target Object calling emit, or symbol describing target (such as static method name)
* @param array|ArrayAccess $argv Array of arguments; typically, should be associative
* @param null|callable $callback Trigger listeners until return value of this callback evaluate to true
* @return ResponseCollection All listener return values
* @throws Exception\InvalidCallbackException
*/
public function trigger($event, $target = null, $argv = [], $callback = null)
{
if ($event instanceof EventInterface) {
$e = $event;
$event = $e->getName();
$callback = $target;
} elseif ($target instanceof EventInterface) {
$e = $target;
$e->setName($event);
$callback = $argv;
} elseif ($argv instanceof EventInterface) {
$e = $argv;
$e->setName($event);
$e->setTarget($target);
} else {
$e = new $this->eventClass();
$e->setName($event);
$e->setTarget($target);
$e->setParams($argv);
}
if ($callback && !is_callable($callback)) {
throw new Exception\InvalidCallbackException('Invalid callback provided');
}
return $this->triggerListeners($event, $e, $callback);
}
/**
* Trigger listeners until return value of one causes a callback to
* evaluate to true
*
* Triggers listeners until the provided callback evaluates the return
* value of one as true, or until all listeners have been executed.
*
* @deprecated The signature of this method will change in 3.0.0.
* See {@link https://github.com/zendframework/zend-eventmanager/blob/develop/doc/book/migration/changed.md}
* for details.
* @param string|EventInterface $event
* @param string|object $target Object calling emit, or symbol describing target (such as static method name)
* @param array|ArrayAccess $argv Array of arguments; typically, should be associative
* @param callable $callback
* @return ResponseCollection
* @throws Exception\InvalidCallbackException if invalid callable provided
*/
public function triggerUntil($event, $target, $argv = null, $callback = null)
{
trigger_error(
'This method is deprecated and will be removed in the future. Please use trigger() instead.',
E_USER_DEPRECATED
);
return $this->trigger($event, $target, $argv, $callback);
}
/**
* Trigger an event instance.
*
* @param EventInterface $event
* @return ResponseCollection
*/
public function triggerEvent(EventInterface $event)
{
return $this->triggerListeners($event->getName(), $event);
}
/**
* Trigger an event instance, short-circuiting if a listener response evaluates true via the callback.
*
* @param callable $callback
* @param EventInterface $event
* @return ResponseCollection
*/
public function triggerEventUntil(callable $callback, EventInterface $event)
{
return $this->triggerListeners($event->getName(), $event, $callback);
}
/**
* Attach a listener to an event
*
* The first argument is the event, and the next argument describes a
* callback that will respond to that event. A CallbackHandler instance
* describing the event listener combination will be returned.
*
* The last argument indicates a priority at which the event should be
* executed. By default, this value is 1; however, you may set it for any
* integer value. Higher values have higher priority (i.e., execute first).
*
* You can specify "*" for the event name. In such cases, the listener will
* be triggered for every event.
*
* @param string|array|ListenerAggregateInterface $event An event or array of event names. If a ListenerAggregateInterface, proxies to {@link attachAggregate()}.
* @param callable|int $callback If string $event provided, expects PHP callback; for a ListenerAggregateInterface $event, this will be the priority
* @param int $priority If provided, the priority at which to register the callable
* @return CallbackHandler|mixed CallbackHandler if attaching callable (to allow later unsubscribe); mixed if attaching aggregate
* @throws Exception\InvalidArgumentException
*/
public function attach($event, $callback = null, $priority = 1)
{
// Proxy ListenerAggregateInterface arguments to attachAggregate()
if ($event instanceof ListenerAggregateInterface) {
return $this->attachAggregate($event, $callback);
}
// Null callback is invalid
if (null === $callback) {
throw new Exception\InvalidArgumentException(sprintf(
'%s: expects a callback; none provided',
__METHOD__
));
}
// Array of events should be registered individually, and return an array of all listeners
if (is_array($event)) {
$listeners = [];
foreach ($event as $name) {
$listeners[] = $this->attach($name, $callback, $priority);
}
return $listeners;
}
// If we don't have a priority queue for the event yet, create one
if (empty($this->events[$event])) {
$this->events[$event] = new PriorityQueue();
}
// Create a callback handler, setting the event and priority in its metadata
$listener = new CallbackHandler($callback, ['event' => $event, 'priority' => $priority]);
// Inject the callback handler into the queue
$this->events[$event]->insert($listener, $priority);
return $listener;
}
/**
* Attach a listener aggregate
*
* Listener aggregates accept an EventManagerInterface instance, and call attach()
* one or more times, typically to attach to multiple events using local
* methods.
*
* @deprecated This method is deprecated with 2.6.0, and will be removed in 3.0.0.
* See {@link https://github.com/zendframework/zend-eventmanager/blob/develop/doc/book/migration/removed.md}
* for details.
* @param ListenerAggregateInterface $aggregate
* @param int $priority If provided, a suggested priority for the aggregate to use
* @return mixed return value of {@link ListenerAggregateInterface::attach()}
*/
public function attachAggregate(ListenerAggregateInterface $aggregate, $priority = 1)
{
return $aggregate->attach($this, $priority);
}
/**
* Unsubscribe a listener from an event
*
* @param CallbackHandler|ListenerAggregateInterface $listener
* @return bool Returns true if event and listener found, and unsubscribed; returns false if either event or listener not found
* @throws Exception\InvalidArgumentException if invalid listener provided
*/
public function detach($listener)
{
if ($listener instanceof ListenerAggregateInterface) {
return $this->detachAggregate($listener);
}
if (!$listener instanceof CallbackHandler) {
throw new Exception\InvalidArgumentException(sprintf(
'%s: expected a ListenerAggregateInterface or CallbackHandler; received "%s"',
__METHOD__,
(is_object($listener) ? get_class($listener) : gettype($listener))
));
}
$event = $listener->getMetadatum('event');
if (!$event || empty($this->events[$event])) {
return false;
}
$return = $this->events[$event]->remove($listener);
if (!$return) {
return false;
}
if (!count($this->events[$event])) {
unset($this->events[$event]);
}
return true;
}
/**
* Detach a listener aggregate
*
* Listener aggregates accept an EventManagerInterface instance, and call detach()
* of all previously attached listeners.
*
* @deprecated This method is deprecated with 2.6.0, and will be removed in 3.0.0.
* See {@link https://github.com/zendframework/zend-eventmanager/blob/develop/doc/book/migration/removed.md}
* for details.
* @param ListenerAggregateInterface $aggregate
* @return mixed return value of {@link ListenerAggregateInterface::detach()}
*/
public function detachAggregate(ListenerAggregateInterface $aggregate)
{
return $aggregate->detach($this);
}
/**
* Retrieve all registered events
*
* @deprecated This method is deprecated with 2.6.0, and will be removed in 3.0.0.
* See {@link https://github.com/zendframework/zend-eventmanager/blob/develop/doc/book/migration/removed.md}
* for details.
* @return array
*/
public function getEvents()
{
return array_keys($this->events);
}
/**
* Retrieve all listeners for a given event
*
* @deprecated This method is deprecated with 2.6.0, and will be removed in 3.0.0.
* See {@link https://github.com/zendframework/zend-eventmanager/blob/develop/doc/book/migration/removed.md}
* for details.
* @param string $event
* @return PriorityQueue
*/
public function getListeners($event)
{
if (!array_key_exists($event, $this->events)) {
return new PriorityQueue();
}
return $this->events[$event];
}
/**
* Clear all listeners for a given event
*
* @param string $event
* @return void
*/
public function clearListeners($event)
{
if (!empty($this->events[$event])) {
unset($this->events[$event]);
}
}
/**
* Prepare arguments
*
* Use this method if you want to be able to modify arguments from within a
* listener. It returns an ArrayObject of the arguments, which may then be
* passed to trigger().
*
* @param array $args
* @return ArrayObject
*/
public function prepareArgs(array $args)
{
return new ArrayObject($args);
}
/**
* Trigger listeners
*
* Actual functionality for triggering listeners, to which trigger() delegate.
*
* @param string $event Event name
* @param EventInterface $e
* @param null|callable $callback
* @return ResponseCollection
*/
protected function triggerListeners($event, EventInterface $e, $callback = null)
{
// Initial value of stop propagation flag should be false
$e->stopPropagation(false);
$responses = new ResponseCollection;
$listeners = $this->getListeners($event);
// Add shared/wildcard listeners to the list of listeners,
// but don't modify the listeners object
$sharedListeners = $this->getSharedListeners($event);
$sharedWildcardListeners = $this->getSharedListeners('*');
$wildcardListeners = $this->getListeners('*');
if (count($sharedListeners) || count($sharedWildcardListeners) || count($wildcardListeners)) {
$listeners = clone $listeners;
// Shared listeners on this specific event
$this->insertListeners($listeners, $sharedListeners);
// Shared wildcard listeners
$this->insertListeners($listeners, $sharedWildcardListeners);
// Add wildcard listeners
$this->insertListeners($listeners, $wildcardListeners);
}
foreach ($listeners as $listener) {
$listenerCallback = $listener->getCallback();
// Trigger the listener's callback, and push its result onto the
// response collection
$responses->push(call_user_func($listenerCallback, $e));
// If the event was asked to stop propagating, do so
if ($e->propagationIsStopped()) {
$responses->setStopped(true);
break;
}
// If the result causes our validation callback to return true,
// stop propagation
if ($callback && call_user_func($callback, $responses->last())) {
$responses->setStopped(true);
break;
}
}
return $responses;
}
/**
* Get list of all listeners attached to the shared event manager for
* identifiers registered by this instance
*
* @param string $event
* @return array
*/
protected function getSharedListeners($event)
{
if (!$sharedManager = $this->getSharedManager()) {
return [];
}
$identifiers = $this->getIdentifiers();
//Add wildcard id to the search, if not already added
if (!in_array('*', $identifiers)) {
$identifiers[] = '*';
}
$sharedListeners = [];
foreach ($identifiers as $id) {
if (!$listeners = $sharedManager->getListeners($id, $event)) {
continue;
}
if (!is_array($listeners) && !($listeners instanceof Traversable)) {
continue;
}
foreach ($listeners as $listener) {
if (!$listener instanceof CallbackHandler) {
continue;
}
$sharedListeners[] = $listener;
}
}
return $sharedListeners;
}
/**
* Add listeners to the master queue of listeners
*
* Used to inject shared listeners and wildcard listeners.
*
* @param PriorityQueue $masterListeners
* @param array|Traversable $listeners
* @return void
*/
protected function insertListeners($masterListeners, $listeners)
{
foreach ($listeners as $listener) {
$priority = $listener->getMetadatum('priority');
if (null === $priority) {
$priority = 1;
} elseif (is_array($priority)) {
// If we have an array, likely using PriorityQueue. Grab first
// element of the array, as that's the actual priority.
$priority = array_shift($priority);
}
$masterListeners->insert($listener, $priority);
}
}
}
================================================
FILE: src/Zend/EventManager/src/EventManagerAwareInterface.php
================================================
eventIdentifier property.
*
* @param EventManagerInterface $events
* @return mixed
*/
public function setEventManager(EventManagerInterface $events)
{
$identifiers = [__CLASS__, get_class($this)];
if (isset($this->eventIdentifier)) {
if ((is_string($this->eventIdentifier))
|| (is_array($this->eventIdentifier))
|| ($this->eventIdentifier instanceof Traversable)
) {
$identifiers = array_unique(array_merge($identifiers, (array) $this->eventIdentifier));
} elseif (is_object($this->eventIdentifier)) {
$identifiers[] = $this->eventIdentifier;
}
// silently ignore invalid eventIdentifier types
}
$events->setIdentifiers($identifiers);
$this->events = $events;
if (method_exists($this, 'attachDefaultListeners')) {
$this->attachDefaultListeners();
}
return $this;
}
/**
* Retrieve the event manager
*
* Lazy-loads an EventManager instance if none registered.
*
* @return EventManagerInterface
*/
public function getEventManager()
{
if (!$this->events instanceof EventManagerInterface) {
$this->setEventManager(new EventManager());
}
return $this->events;
}
}
================================================
FILE: src/Zend/EventManager/src/EventManagerInterface.php
================================================
setExtractFlags(self::EXTR_BOTH);
// Iterate and remove any matches
$removed = false;
$items = [];
$this->rewind();
while (!$this->isEmpty()) {
$item = $this->extract();
if ($item['data'] === $datum) {
$removed = true;
continue;
}
$items[] = $item;
}
// Repopulate
foreach ($items as $item) {
$this->insert($item['data'], $item['priority']);
}
$this->setExtractFlags(self::EXTR_DATA);
return $removed;
}
/**
* Iterate the next filter in the chain
*
* Iterates and calls the next filter in the chain.
*
* @param mixed $context
* @param array $params
* @param FilterIterator $chain
* @return mixed
*/
#[ReturnTypeWillChange] public function next($context = null, array $params = [], $chain = null)
{
if (empty($context) || ($chain instanceof FilterIterator && $chain->isEmpty())) {
return;
}
//We can't extract from an empty heap
if ($this->isEmpty()) {
return;
}
$next = $this->extract();
if (!$next instanceof CallbackHandler) {
return;
}
$return = call_user_func($next->getCallback(), $context, $params, $chain);
return $return;
}
}
================================================
FILE: src/Zend/EventManager/src/FilterChain.php
================================================
filters = new Filter\FilterIterator();
}
/**
* Apply the filters
*
* Begins iteration of the filters.
*
* @param mixed $context Object under observation
* @param mixed $argv Associative array of arguments
* @return mixed
*/
public function run($context, array $argv = [])
{
$chain = clone $this->getFilters();
if ($chain->isEmpty()) {
return;
}
$next = $chain->extract();
if (!$next instanceof CallbackHandler) {
return;
}
return call_user_func($next->getCallback(), $context, $argv, $chain);
}
/**
* Connect a filter to the chain
*
* @param callable $callback PHP Callback
* @param int $priority Priority in the queue at which to execute; defaults to 1 (higher numbers == higher priority)
* @return CallbackHandler (to allow later unsubscribe)
* @throws Exception\InvalidCallbackException
*/
public function attach($callback, $priority = 1)
{
if (empty($callback)) {
throw new Exception\InvalidCallbackException('No callback provided');
}
$filter = new CallbackHandler($callback, ['priority' => $priority]);
$this->filters->insert($filter, $priority);
return $filter;
}
/**
* Detach a filter from the chain
*
* @param CallbackHandler $filter
* @return bool Returns true if filter found and unsubscribed; returns false otherwise
*/
public function detach(CallbackHandler $filter)
{
return $this->filters->remove($filter);
}
/**
* Retrieve all filters
*
* @return Filter\FilterIterator
*/
public function getFilters()
{
return $this->filters;
}
/**
* Clear all filters
*
* @return void
*/
public function clearFilters()
{
$this->filters = new Filter\FilterIterator();
}
/**
* Return current responses
*
* Only available while the chain is still being iterated. Returns the
* current ResponseCollection.
*
* @return void
*/
public function getResponses()
{
return;
}
}
================================================
FILE: src/Zend/EventManager/src/GlobalEventManager.php
================================================
trigger($event, $context, $argv, $callback);
}
/**
* Trigger listeners until return value of one causes a callback to evaluate
* to true.
*
* @param string $event
* @param string|object $context
* @param array|object $argv
* @param callable $callback
* @return ResponseCollection
* @deprecated Please use trigger()
*/
public static function triggerUntil($event, $context, $argv, $callback)
{
trigger_error(
'This method is deprecated and will be removed in the future. Please use trigger() instead.',
E_USER_DEPRECATED
);
return static::trigger($event, $context, $argv, $callback);
}
/**
* Attach a listener to an event
*
* @param string $event
* @param callable $callback
* @param int $priority
* @return CallbackHandler
*/
public static function attach($event, $callback, $priority = 1)
{
return static::getEventCollection()->attach($event, $callback, $priority);
}
/**
* Detach a callback from a listener
*
* @param CallbackHandler $listener
* @return bool
*/
public static function detach(CallbackHandler $listener)
{
return static::getEventCollection()->detach($listener);
}
/**
* Retrieve list of events this object manages
*
* @return array
*/
public static function getEvents()
{
return static::getEventCollection()->getEvents();
}
/**
* Retrieve all listeners for a given event
*
* @param string $event
* @return PriorityQueue|array
*/
public static function getListeners($event)
{
return static::getEventCollection()->getListeners($event);
}
/**
* Clear all listeners for a given event
*
* @param string $event
* @return void
*/
public static function clearListeners($event)
{
static::getEventCollection()->clearListeners($event);
}
}
================================================
FILE: src/Zend/EventManager/src/ListenerAggregateInterface.php
================================================
listeners as $index => $callback) {
if ($events->detach($callback)) {
unset($this->listeners[$index]);
}
}
}
}
================================================
FILE: src/Zend/EventManager/src/ProvidesEvents.php
================================================
stopped;
}
/**
* Mark the collection as stopped (or its opposite)
*
* @param bool $flag
* @return ResponseCollection
*/
public function setStopped($flag)
{
$this->stopped = (bool) $flag;
return $this;
}
/**
* Convenient access to the first handler return value.
*
* @return mixed The first handler return value
*/
public function first()
{
return parent::bottom();
}
/**
* Convenient access to the last handler return value.
*
* If the collection is empty, returns null. Otherwise, returns value
* returned by last handler.
*
* @return mixed The last handler return value
*/
public function last()
{
if (count($this) === 0) {
return;
}
return parent::top();
}
/**
* Check if any of the responses match the given value.
*
* @param mixed $value The value to look for among responses
* @return bool
*/
public function contains($value)
{
foreach ($this as $response) {
if ($response === $value) {
return true;
}
}
return false;
}
}
================================================
FILE: src/Zend/EventManager/src/SharedEventAggregateAwareInterface.php
================================================
* $sharedEventManager = new SharedEventManager();
* $sharedEventManager->attach(
* array('My\Resource\AbstractResource', 'My\Resource\EntityResource'),
* 'getAll',
* function ($e) use ($cache) {
* if (!$id = $e->getParam('id', false)) {
* return;
* }
* if (!$data = $cache->load(get_class($resource) . '::getOne::' . $id )) {
* return;
* }
* return $data;
* }
* );
*
*
* @param string|array $id Identifier(s) for event emitting component(s)
* @param string $event
* @param callable $callback PHP Callback
* @param int $priority Priority at which listener should execute
* @return CallbackHandler|array Either CallbackHandler or array of CallbackHandlers
*/
public function attach($id, $event, $callback, $priority = 1)
{
$ids = (array) $id;
$listeners = [];
foreach ($ids as $id) {
if (!array_key_exists($id, $this->identifiers)) {
$this->identifiers[$id] = new EventManager($id);
}
$listeners[] = $this->identifiers[$id]->attach($event, $callback, $priority);
}
if (count($listeners) > 1) {
return $listeners;
}
return $listeners[0];
}
/**
* Attach a listener aggregate
*
* Listener aggregates accept an EventManagerInterface instance, and call attachShared()
* one or more times, typically to attach to multiple events using local
* methods.
*
* @param SharedListenerAggregateInterface $aggregate
* @param int $priority If provided, a suggested priority for the aggregate to use
* @return mixed return value of {@link ListenerAggregateInterface::attachShared()}
*/
public function attachAggregate(SharedListenerAggregateInterface $aggregate, $priority = 1)
{
return $aggregate->attachShared($this, $priority);
}
/**
* Detach a listener from an event offered by a given resource
*
* @param string|int $id
* @param CallbackHandler $listener
* @return bool Returns true if event and listener found, and unsubscribed; returns false if either event or listener not found
*/
public function detach($id, CallbackHandler $listener)
{
if (!array_key_exists($id, $this->identifiers)) {
return false;
}
return $this->identifiers[$id]->detach($listener);
}
/**
* Detach a listener aggregate
*
* Listener aggregates accept a SharedEventManagerInterface instance, and call detachShared()
* of all previously attached listeners.
*
* @param SharedListenerAggregateInterface $aggregate
* @return mixed return value of {@link SharedListenerAggregateInterface::detachShared()}
*/
public function detachAggregate(SharedListenerAggregateInterface $aggregate)
{
return $aggregate->detachShared($this);
}
/**
* Retrieve all registered events for a given resource
*
* @param string|int $id
*
* @return false
*@deprecated This method is deprecated with 2.6.0, and will be removed in 3.0.0.
* See {@link https://github.com/zendframework/zend-eventmanager/blob/develop/doc/book/migration/removed.md}
* for details.
*/
public function getEvents($id)
{
if (!array_key_exists($id, $this->identifiers)) {
//Check if there are any id wildcards listeners
if ('*' != $id && array_key_exists('*', $this->identifiers)) {
return $this->identifiers['*']->getEvents();
}
return false;
}
return $this->identifiers[$id]->getEvents();
}
/**
* Retrieve all listeners for a given identifier and event
*
* @param string|int $id
* @param string|int $event
* @return false|PriorityQueue
*/
public function getListeners($id, $event)
{
if (!array_key_exists($id, $this->identifiers)) {
return false;
}
return $this->identifiers[$id]->getListeners($event);
}
/**
* Clear all listeners for a given identifier, optionally for a specific event
*
* @param string|int $id
* @param null|string $event
* @return bool
*/
public function clearListeners($id, $event = null)
{
if (!array_key_exists($id, $this->identifiers)) {
return false;
}
if (null === $event) {
unset($this->identifiers[$id]);
return true;
}
return $this->identifiers[$id]->clearListeners($event);
}
}
================================================
FILE: src/Zend/EventManager/src/SharedEventManagerAwareInterface.php
================================================
getListeners($event);
return $this->traverseListeners($listeners, $withPriority);
}
/**
* Generator for traversing listeners in priority order.
*
* @param PriorityQueue $listeners
* @param bool $withPriority When true, yields priority as key.
*/
public function traverseListeners(PriorityQueue $queue, $withPriority = false)
{
foreach ($queue as $handler) {
$listener = $handler->getCallback();
if ($withPriority) {
$priority = (int) $handler->getMetadatum('priority');
yield $priority => $listener;
} else {
yield $listener;
}
}
}
}
================================================
FILE: src/Zend/Filter/LICENSE.md
================================================
Copyright (c) 2005-2019, Zend Technologies USA, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
- Neither the name of Zend Technologies USA, Inc. nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================
FILE: src/Zend/Filter/README.md
================================================
# zend-filter
[](https://secure.travis-ci.org/zendframework/zend-filter)
[](https://coveralls.io/github/zendframework/zend-filter?branch=master)
The `Zend\Filter` component provides a set of commonly needed data filters. It
also provides a simple filter chaining mechanism by which multiple filters may
be applied to a single datum in a user-defined order.
- File issues at https://github.com/zendframework/zend-filter/issues
- Documentation is at https://docs.zendframework.com/zend-filter/
================================================
FILE: src/Zend/Filter/src/AbstractDateDropdown.php
================================================
setOptions($options);
}
}
/**
* @param bool $nullOnAllEmpty
* @return self
*/
public function setNullOnAllEmpty($nullOnAllEmpty)
{
$this->nullOnAllEmpty = $nullOnAllEmpty;
return $this;
}
/**
* @return bool
*/
public function isNullOnAllEmpty()
{
return $this->nullOnAllEmpty;
}
/**
* @param bool $nullOnEmpty
* @return self
*/
public function setNullOnEmpty($nullOnEmpty)
{
$this->nullOnEmpty = $nullOnEmpty;
return $this;
}
/**
* @return bool
*/
public function isNullOnEmpty()
{
return $this->nullOnEmpty;
}
/**
* Attempts to filter an array of date/time information to a formatted
* string.
*
* @param mixed $value
* @return mixed
* @throws Exception\RuntimeException If filtering $value is impossible
*/
public function filter($value)
{
if (! is_array($value)) {
// nothing to do
return $value;
}
// Convert the date to a specific format
if ($this->isNullOnEmpty()
&& array_reduce($value, __CLASS__ . '::reduce', false)
) {
return null;
}
if ($this->isNullOnAllEmpty()
&& array_reduce($value, __CLASS__ . '::reduce', true)
) {
return null;
}
$this->filterable($value);
ksort($value);
$value = vsprintf($this->format, $value);
return $value;
}
/**
* Ensures there are enough inputs in the array to properly format the date.
*
* @param $value
* @throws Exception\RuntimeException
*/
protected function filterable($value)
{
if (count($value) !== $this->expectedInputs) {
throw new Exception\RuntimeException(
sprintf(
'There are not enough values in the array to filter this date (Required: %d, Received: %d)',
$this->expectedInputs,
count($value)
)
);
}
}
/**
* Reduce to a single value
*
* @param string $soFar
* @param string $value
* @return bool
*/
public static function reduce($soFar, $value)
{
return $soFar || empty($value);
}
}
================================================
FILE: src/Zend/Filter/src/AbstractFilter.php
================================================
$value) {
$setter = 'set' . str_replace(' ', '', ucwords(str_replace('_', ' ', $key)));
if (method_exists($this, $setter)) {
$this->{$setter}($value);
} elseif (array_key_exists($key, $this->options)) {
$this->options[$key] = $value;
} else {
throw new Exception\InvalidArgumentException(
sprintf(
'The option "%s" does not have a matching %s setter method or options[%s] array key',
$key,
$setter,
$key
)
);
}
}
return $this;
}
/**
* Retrieve options representing object state
*
* @return array
*/
public function getOptions()
{
return $this->options;
}
/**
* Invoke filter as a command
*
* Proxies to {@link filter()}
*
* @param mixed $value
* @throws Exception\ExceptionInterface If filtering $value is impossible
* @return mixed
*/
public function __invoke($value)
{
return $this->filter($value);
}
/**
* @param mixed $options
* @return bool
*/
protected static function isOptions($options)
{
return (is_array($options) || $options instanceof Traversable);
}
}
================================================
FILE: src/Zend/Filter/src/AbstractUnicode.php
================================================
options['encoding'] = $encoding;
return $this;
}
/**
* Returns the set encoding
*
* @return string
*/
public function getEncoding()
{
if ($this->options['encoding'] === null && function_exists('mb_internal_encoding')) {
$this->options['encoding'] = mb_internal_encoding();
}
return $this->options['encoding'];
}
}
================================================
FILE: src/Zend/Filter/src/BaseName.php
================================================
setOptions($options);
}
}
/**
* Determine whether the in_array() call should be "strict" or not. See in_array docs.
*
* @param bool $strict
*/
public function setStrict($strict = true)
{
$this->strict = (bool) $strict;
}
/**
* Returns whether the in_array() call should be "strict" or not. See in_array docs.
*
* @return boolean
*/
public function getStrict()
{
return $this->strict;
}
/**
* Set the list of items to black-list.
*
* @param array|Traversable $list
*/
public function setList($list = [])
{
if (! is_array($list)) {
$list = ArrayUtils::iteratorToArray($list);
}
$this->list = $list;
}
/**
* Get the list of items to black-list
*
* @return array
*/
public function getList()
{
return $this->list;
}
/**
* {@inheritDoc}
*
* Will return null if $value is present in the black-list. If $value is NOT present then it will return $value.
*/
public function filter($value)
{
return in_array($value, $this->getList(), $this->getStrict()) ? null : $value;
}
}
================================================
FILE: src/Zend/Filter/src/Boolean.php
================================================
'boolean',
self::TYPE_INTEGER => 'integer',
self::TYPE_FLOAT => 'float',
self::TYPE_STRING => 'string',
self::TYPE_ZERO_STRING => 'zero',
self::TYPE_EMPTY_ARRAY => 'array',
self::TYPE_NULL => 'null',
self::TYPE_PHP => 'php',
self::TYPE_FALSE_STRING => 'false',
self::TYPE_LOCALIZED => 'localized',
self::TYPE_ALL => 'all',
];
/**
* @var array
*/
protected $options = [
'type' => self::TYPE_PHP,
'casting' => true,
'translations' => [],
];
/**
* Constructor
*
* @param int|string|array|Traversable|null $typeOrOptions
* @param bool $casting
* @param array $translations
*/
public function __construct($typeOrOptions = null, $casting = true, $translations = [])
{
if ($typeOrOptions !== null) {
if ($typeOrOptions instanceof Traversable) {
$typeOrOptions = ArrayUtils::iteratorToArray($typeOrOptions);
}
if (is_array($typeOrOptions)) {
if (isset($typeOrOptions['type'])
|| isset($typeOrOptions['casting'])
|| isset($typeOrOptions['translations'])
) {
$this->setOptions($typeOrOptions);
} else {
$this->setType($typeOrOptions);
$this->setCasting($casting);
$this->setTranslations($translations);
}
} else {
$this->setType($typeOrOptions);
$this->setCasting($casting);
$this->setTranslations($translations);
}
}
}
/**
* Set boolean types
*
* @param int|string|array $type
* @throws Exception\InvalidArgumentException
* @return self
*/
public function setType($type = null)
{
if (is_array($type)) {
$detected = 0;
foreach ($type as $value) {
if (is_int($value)) {
$detected |= $value;
} elseif (($found = array_search($value, $this->constants, true)) !== false) {
$detected |= $found;
}
}
$type = $detected;
} elseif (is_string($type) && ($found = array_search($type, $this->constants, true)) !== false) {
$type = $found;
}
if (! is_int($type) || ($type < 0) || ($type > self::TYPE_ALL)) {
throw new Exception\InvalidArgumentException(sprintf(
'Unknown type value "%s" (%s)',
$type,
gettype($type)
));
}
$this->options['type'] = $type;
return $this;
}
/**
* Returns defined boolean types
*
* @return int
*/
public function getType()
{
return $this->options['type'];
}
/**
* Set the working mode
*
* @param bool $flag When true this filter works like cast
* When false it recognises only true and false
* and all other values are returned as is
* @return self
*/
public function setCasting($flag = true)
{
$this->options['casting'] = (bool) $flag;
return $this;
}
/**
* Returns the casting option
*
* @return bool
*/
public function getCasting()
{
return $this->options['casting'];
}
/**
* @param array|Traversable $translations
* @throws Exception\InvalidArgumentException
* @return self
*/
public function setTranslations($translations)
{
if (! is_array($translations) && ! $translations instanceof Traversable) {
throw new Exception\InvalidArgumentException(sprintf(
'"%s" expects an array or Traversable; received "%s"',
__METHOD__,
(is_object($translations) ? get_class($translations) : gettype($translations))
));
}
foreach ($translations as $message => $flag) {
$this->options['translations'][$message] = (bool) $flag;
}
return $this;
}
/**
* @return array
*/
public function getTranslations()
{
return $this->options['translations'];
}
/**
* Defined by Zend\Filter\FilterInterface
*
* Returns a boolean representation of $value
*
* @param null|array|bool|float|int|string $value
* @return bool|mixed
*/
public function filter($value)
{
$type = $this->getType();
$casting = $this->getCasting();
// LOCALIZED
if ($type & self::TYPE_LOCALIZED) {
if (is_string($value)) {
if (isset($this->options['translations'][$value])) {
return (bool) $this->options['translations'][$value];
}
}
}
// FALSE_STRING ('false')
if ($type & self::TYPE_FALSE_STRING) {
if (is_string($value) && strtolower($value) === 'false') {
return false;
}
if (! $casting && is_string($value) && strtolower($value) === 'true') {
return true;
}
}
// NULL (null)
if ($type & self::TYPE_NULL) {
if ($value === null) {
return false;
}
}
// EMPTY_ARRAY (array())
if ($type & self::TYPE_EMPTY_ARRAY) {
if (is_array($value) && $value === []) {
return false;
}
}
// ZERO_STRING ('0')
if ($type & self::TYPE_ZERO_STRING) {
if (is_string($value) && $value === '0') {
return false;
}
if (! $casting && is_string($value) && $value === '1') {
return true;
}
}
// STRING ('')
if ($type & self::TYPE_STRING) {
if (is_string($value) && $value === '') {
return false;
}
}
// FLOAT (0.0)
if ($type & self::TYPE_FLOAT) {
if (is_float($value) && $value === 0.0) {
return false;
}
if (! $casting && is_float($value) && $value === 1.0) {
return true;
}
}
// INTEGER (0)
if ($type & self::TYPE_INTEGER) {
if (is_int($value) && $value === 0) {
return false;
}
if (! $casting && is_int($value) && $value === 1) {
return true;
}
}
// BOOLEAN (false)
if ($type & self::TYPE_BOOLEAN) {
if (is_bool($value)) {
return $value;
}
}
if ($casting) {
return true;
}
return $value;
}
}
================================================
FILE: src/Zend/Filter/src/Callback.php
================================================
null,
'callback_params' => []
];
/**
* @param callable|array|string|Traversable $callbackOrOptions
* @param array $callbackParams
*/
public function __construct($callbackOrOptions = [], $callbackParams = [])
{
if (is_callable($callbackOrOptions) || is_string($callbackOrOptions)) {
$this->setCallback($callbackOrOptions);
$this->setCallbackParams($callbackParams);
} else {
$this->setOptions($callbackOrOptions);
}
}
/**
* Sets a new callback for this filter
*
* @param callable $callback
* @throws Exception\InvalidArgumentException
* @return self
*/
public function setCallback($callback)
{
if (is_string($callback) && class_exists($callback)) {
$callback = new $callback();
}
if (! is_callable($callback)) {
throw new Exception\InvalidArgumentException(
'Invalid parameter for callback: must be callable'
);
}
$this->options['callback'] = $callback;
return $this;
}
/**
* Returns the set callback
*
* @return callable
*/
public function getCallback()
{
return $this->options['callback'];
}
/**
* Sets parameters for the callback
*
* @param array $params
* @return self
*/
public function setCallbackParams($params)
{
$this->options['callback_params'] = (array) $params;
return $this;
}
/**
* Get parameters for the callback
*
* @return array
*/
public function getCallbackParams()
{
return $this->options['callback_params'];
}
/**
* Calls the filter per callback
*
* @param mixed $value Options for the set callable
* @return mixed Result from the filter which was called
*/
public function filter($value)
{
$params = (array) $this->options['callback_params'];
array_unshift($params, $value);
return call_user_func_array($this->options['callback'], $params);
}
}
================================================
FILE: src/Zend/Filter/src/Compress/AbstractCompressionAlgorithm.php
================================================
setOptions($options);
}
}
/**
* Returns one or all set options
*
* @param string|null $option Option to return
* @return mixed
*/
public function getOptions($option = null)
{
if ($option === null) {
return $this->options;
}
if (! isset($this->options[$option])) {
return null;
}
return $this->options[$option];
}
/**
* Sets all or one option
*
* @param array $options
* @return self
*/
public function setOptions(array $options)
{
foreach ($options as $key => $option) {
$method = 'set' . $key;
if (method_exists($this, $method)) {
$this->$method($option);
}
}
return $this;
}
}
================================================
FILE: src/Zend/Filter/src/Compress/Bz2.php
================================================
Blocksize to use from 0-9
* 'archive' => Archive to use
* )
*
* @var array
*/
protected $options = [
'blocksize' => 4,
'archive' => null,
];
/**
* Class constructor
*
* @param null|array|\Traversable $options (Optional) Options to set
* @throws Exception\ExtensionNotLoadedException if bz2 extension not loaded
*/
public function __construct($options = null)
{
if (! extension_loaded('bz2')) {
throw new Exception\ExtensionNotLoadedException('This filter needs the bz2 extension');
}
parent::__construct($options);
}
/**
* Returns the set blocksize
*
* @return int
*/
public function getBlocksize()
{
return $this->options['blocksize'];
}
/**
* Sets a new blocksize
*
* @param int $blocksize
* @throws Exception\InvalidArgumentException
* @return self
*/
public function setBlocksize($blocksize)
{
if (($blocksize < 0) || ($blocksize > 9)) {
throw new Exception\InvalidArgumentException('Blocksize must be between 0 and 9');
}
$this->options['blocksize'] = (int) $blocksize;
return $this;
}
/**
* Returns the set archive
*
* @return string
*/
public function getArchive()
{
return $this->options['archive'];
}
/**
* Sets the archive to use for de-/compression
*
* @param string $archive Archive to use
* @return self
*/
public function setArchive($archive)
{
$this->options['archive'] = (string) $archive;
return $this;
}
/**
* Compresses the given content
*
* @param string $content
* @return string
* @throws Exception\RuntimeException
*/
public function compress($content)
{
$archive = $this->getArchive();
if (! empty($archive)) {
$file = bzopen($archive, 'w');
if (! $file) {
throw new Exception\RuntimeException("Error opening the archive '" . $archive . "'");
}
bzwrite($file, $content);
bzclose($file);
$compressed = true;
} else {
$compressed = bzcompress($content, $this->getBlocksize());
}
if (is_int($compressed)) {
throw new Exception\RuntimeException('Error during compression');
}
return $compressed;
}
/**
* Decompresses the given content
*
* @param string $content
* @return string
* @throws Exception\RuntimeException
*/
public function decompress($content)
{
$archive = $this->getArchive();
//check if there are null byte characters before doing a file_exists check
if (! str_contains($content, "\0") && file_exists($content)) {
$archive = $content;
}
if (file_exists($archive)) {
$file = bzopen($archive, 'r');
if (! $file) {
throw new Exception\RuntimeException("Error opening the archive '" . $content . "'");
}
$compressed = bzread($file);
bzclose($file);
} else {
$compressed = bzdecompress($content);
}
if (is_int($compressed)) {
throw new Exception\RuntimeException('Error during decompression');
}
return $compressed;
}
/**
* Returns the adapter name
*
* @return string
*/
public function toString()
{
return 'Bz2';
}
}
================================================
FILE: src/Zend/Filter/src/Compress/CompressionAlgorithmInterface.php
================================================
Compression level 0-9
* 'mode' => Compression mode, can be 'compress', 'deflate'
* 'archive' => Archive to use
* )
*
* @var array
*/
protected $options = [
'level' => 9,
'mode' => 'compress',
'archive' => null,
];
/**
* Class constructor
*
* @param null|array|\Traversable $options (Optional) Options to set
* @throws Exception\ExtensionNotLoadedException if zlib extension not loaded
*/
public function __construct($options = null)
{
if (! extension_loaded('zlib')) {
throw new Exception\ExtensionNotLoadedException('This filter needs the zlib extension');
}
parent::__construct($options);
}
/**
* Returns the set compression level
*
* @return int
*/
public function getLevel()
{
return $this->options['level'];
}
/**
* Sets a new compression level
*
* @param int $level
* @throws Exception\InvalidArgumentException
* @return self
*/
public function setLevel($level)
{
if (($level < 0) || ($level > 9)) {
throw new Exception\InvalidArgumentException('Level must be between 0 and 9');
}
$this->options['level'] = (int) $level;
return $this;
}
/**
* Returns the set compression mode
*
* @return string
*/
public function getMode()
{
return $this->options['mode'];
}
/**
* Sets a new compression mode
*
* @param string $mode Supported are 'compress', 'deflate' and 'file'
* @return self
* @throws Exception\InvalidArgumentException for invalid $mode value
*/
public function setMode($mode)
{
if ($mode !== 'compress' && $mode !== 'deflate') {
throw new Exception\InvalidArgumentException('Given compression mode not supported');
}
$this->options['mode'] = $mode;
return $this;
}
/**
* Returns the set archive
*
* @return string
*/
public function getArchive()
{
return $this->options['archive'];
}
/**
* Sets the archive to use for de-/compression
*
* @param string $archive Archive to use
* @return self
*/
public function setArchive($archive)
{
$this->options['archive'] = (string) $archive;
return $this;
}
/**
* Compresses the given content
*
* @param string $content
* @return string
* @throws Exception\RuntimeException if unable to open archive or error during decompression
*/
public function compress($content)
{
$archive = $this->getArchive();
if (! empty($archive)) {
$file = gzopen($archive, 'w' . $this->getLevel());
if (! $file) {
throw new Exception\RuntimeException("Error opening the archive '" . $this->options['archive'] . "'");
}
gzwrite($file, $content);
gzclose($file);
$compressed = true;
} elseif ($this->options['mode'] === 'deflate') {
$compressed = gzdeflate($content, $this->getLevel());
} else {
$compressed = gzcompress($content, $this->getLevel());
}
if (! $compressed) {
throw new Exception\RuntimeException('Error during compression');
}
return $compressed;
}
/**
* Decompresses the given content
*
* @param string $content
* @return string
* @throws Exception\RuntimeException if unable to open archive or error during decompression
*/
public function decompress($content)
{
$archive = $this->getArchive();
$mode = $this->getMode();
//check if there are null byte characters before doing a file_exists check
if (! str_contains($content, "\0") && file_exists($content)) {
$archive = $content;
}
if (file_exists($archive)) {
$handler = fopen($archive, 'rb');
if (! $handler) {
throw new Exception\RuntimeException("Error opening the archive '" . $archive . "'");
}
fseek($handler, -4, SEEK_END);
$packet = fread($handler, 4);
$bytes = unpack('V', $packet);
$size = end($bytes);
fclose($handler);
$file = gzopen($archive, 'r');
$compressed = gzread($file, $size);
gzclose($file);
} elseif ($mode === 'deflate') {
$compressed = gzinflate($content);
} else {
$compressed = gzuncompress($content);
}
if ($compressed === false) {
throw new Exception\RuntimeException('Error during decompression');
}
return $compressed;
}
/**
* Returns the adapter name
*
* @return string
*/
public function toString()
{
return 'Gz';
}
}
================================================
FILE: src/Zend/Filter/src/Compress/Lzf.php
================================================
Callback for compression
* 'archive' => Archive to use
* 'password' => Password to use
* 'target' => Target to write the files to
* )
*
* @var array
*/
protected $options = [
'callback' => null,
'archive' => null,
'password' => null,
'target' => '.',
];
/**
* Class constructor
*
* @param array $options (Optional) Options to set
* @throws Exception\ExtensionNotLoadedException if rar extension not loaded
*/
public function __construct($options = null)
{
if (! extension_loaded('rar')) {
throw new Exception\ExtensionNotLoadedException('This filter needs the rar extension');
}
parent::__construct($options);
}
/**
* Returns the set callback for compression
*
* @return string
*/
public function getCallback()
{
return $this->options['callback'];
}
/**
* Sets the callback to use
*
* @param string $callback
* @return self
* @throws Exception\InvalidArgumentException if invalid callback provided
*/
public function setCallback($callback)
{
if (! is_callable($callback)) {
throw new Exception\InvalidArgumentException('Invalid callback provided');
}
$this->options['callback'] = $callback;
return $this;
}
/**
* Returns the set archive
*
* @return string
*/
public function getArchive()
{
return $this->options['archive'];
}
/**
* Sets the archive to use for de-/compression
*
* @param string $archive Archive to use
* @return self
*/
public function setArchive($archive)
{
$archive = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $archive);
$this->options['archive'] = (string) $archive;
return $this;
}
/**
* Returns the set password
*
* @return string
*/
public function getPassword()
{
return $this->options['password'];
}
/**
* Sets the password to use
*
* @param string $password
* @return self
*/
public function setPassword($password)
{
$this->options['password'] = (string) $password;
return $this;
}
/**
* Returns the set targetpath
*
* @return string
*/
public function getTarget()
{
return $this->options['target'];
}
/**
* Sets the targetpath to use
*
* @param string $target
* @return self
* @throws Exception\InvalidArgumentException if specified target directory does not exist
*/
public function setTarget($target)
{
if (! file_exists(dirname($target))) {
throw new Exception\InvalidArgumentException("The directory '$target' does not exist");
}
$target = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, (string) $target);
$this->options['target'] = $target;
return $this;
}
/**
* Compresses the given content
*
* @param string|array $content
* @return string
* @throws Exception\RuntimeException if no callback available, or error during compression
*/
public function compress($content)
{
$callback = $this->getCallback();
if ($callback === null) {
throw new Exception\RuntimeException('No compression callback available');
}
$options = $this->getOptions();
unset($options['callback']);
$result = $callback($options, $content);
if ($result !== true) {
throw new Exception\RuntimeException('Error compressing the RAR Archive');
}
return $this->getArchive();
}
/**
* Decompresses the given content
*
* @param string $content
* @return bool
* @throws Exception\RuntimeException if archive not found, cannot be opened,
* or error during decompression
*/
public function decompress($content)
{
if (! file_exists($content)) {
throw new Exception\RuntimeException('RAR Archive not found');
}
$archive = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, realpath($content));
$password = $this->getPassword();
if ($password !== null) {
$archive = rar_open($archive, $password);
} else {
$archive = rar_open($archive);
}
if (! $archive) {
throw new Exception\RuntimeException('Error opening the RAR Archive');
}
$target = $this->getTarget();
if (! is_dir($target)) {
$target = dirname($target);
}
$filelist = rar_list($archive);
if (! $filelist) {
throw new Exception\RuntimeException("Error reading the RAR Archive");
}
foreach ($filelist as $file) {
$file->extract($target);
}
rar_close($archive);
return true;
}
/**
* Returns the adapter name
*
* @return string
*/
public function toString()
{
return 'Rar';
}
}
================================================
FILE: src/Zend/Filter/src/Compress/Snappy.php
================================================
Archive to use
* 'target' => Target to write the files to
* )
*
* @var array
*/
protected $options = [
'archive' => null,
'target' => '.',
'mode' => null,
];
/**
* Class constructor
*
* @param array $options (Optional) Options to set
* @throws Exception\ExtensionNotLoadedException if Archive_Tar component not available
*/
public function __construct($options = null)
{
if (! class_exists('Archive_Tar')) {
throw new Exception\ExtensionNotLoadedException(
'This filter needs PEAR\'s Archive_Tar component. '
. 'Ensure loading Archive_Tar (registering autoload or require_once)'
);
}
parent::__construct($options);
}
/**
* Returns the set archive
*
* @return string
*/
public function getArchive()
{
return $this->options['archive'];
}
/**
* Sets the archive to use for de-/compression
*
* @param string $archive Archive to use
* @return self
*/
public function setArchive($archive)
{
$archive = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, (string) $archive);
$this->options['archive'] = $archive;
return $this;
}
/**
* Returns the set target path
*
* @return string
*/
public function getTarget()
{
return $this->options['target'];
}
/**
* Sets the target path to use
*
* @param string $target
* @return self
* @throws Exception\InvalidArgumentException if target path does not exist
*/
public function setTarget($target)
{
if (! file_exists(dirname($target))) {
throw new Exception\InvalidArgumentException("The directory '$target' does not exist");
}
$target = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, (string) $target);
$this->options['target'] = $target;
return $this;
}
/**
* Returns the set compression mode
*
* @return string
*/
public function getMode()
{
return $this->options['mode'];
}
/**
* Compression mode to use
*
* Either Gz or Bz2.
*
* @param string $mode
* @return self
* @throws Exception\InvalidArgumentException for invalid $mode values
* @throws Exception\ExtensionNotLoadedException if bz2 mode selected but extension not loaded
* @throws Exception\ExtensionNotLoadedException if gz mode selected but extension not loaded
*/
public function setMode($mode)
{
$mode = strtolower($mode);
if ($mode !== 'bz2' && $mode !== 'gz') {
throw new Exception\InvalidArgumentException("The mode '$mode' is unknown");
}
if ($mode === 'bz2' && ! extension_loaded('bz2')) {
throw new Exception\ExtensionNotLoadedException('This mode needs the bz2 extension');
}
if ($mode === 'gz' && ! extension_loaded('zlib')) {
throw new Exception\ExtensionNotLoadedException('This mode needs the zlib extension');
}
$this->options['mode'] = $mode;
return $this;
}
/**
* Compresses the given content
*
* @param string $content
* @return string
* @throws Exception\RuntimeException if unable to create temporary file
* @throws Exception\RuntimeException if unable to create archive
*/
public function compress($content)
{
$archive = new Archive_Tar($this->getArchive(), $this->getMode());
if (! file_exists($content)) {
$file = $this->getTarget();
if (is_dir($file)) {
$file .= DIRECTORY_SEPARATOR . 'tar.tmp';
}
$result = file_put_contents($file, $content);
if ($result === false) {
throw new Exception\RuntimeException('Error creating the temporary file');
}
$content = $file;
}
if (is_dir($content)) {
// collect all file infos
foreach (new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($content, FilesystemIterator::KEY_AS_PATHNAME),
RecursiveIteratorIterator::SELF_FIRST
) as $directory => $info) {
if ($info->isFile()) {
$file .= $directory;
}
}
$content = $file;
}
$result = $archive->create($content);
if ($result === false) {
throw new Exception\RuntimeException('Error creating the Tar archive');
}
return $this->getArchive();
}
/**
* Decompresses the given content
*
* @param string $content
* @return string
* @throws Exception\RuntimeException if unable to find archive
* @throws Exception\RuntimeException if error occurs decompressing archive
*/
public function decompress($content)
{
$archive = $this->getArchive();
if (file_exists($content)) {
$archive = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, realpath($content));
} elseif (empty($archive) || ! file_exists($archive)) {
throw new Exception\RuntimeException('Tar Archive not found');
}
$archive = new Archive_Tar($archive, $this->getMode());
$target = $this->getTarget();
if (! is_dir($target)) {
$target = dirname($target) . DIRECTORY_SEPARATOR;
}
$result = $archive->extract($target);
if ($result === false) {
throw new Exception\RuntimeException('Error while extracting the Tar archive');
}
return $target;
}
/**
* Returns the adapter name
*
* @return string
*/
public function toString()
{
return 'Tar';
}
}
================================================
FILE: src/Zend/Filter/src/Compress/Zip.php
================================================
Archive to use
* 'password' => Password to use
* 'target' => Target to write the files to
* )
*
* @var array
*/
protected $options = [
'archive' => null,
'target' => null,
];
/**
* Class constructor
*
* @param null|array|\Traversable $options (Optional) Options to set
* @throws Exception\ExtensionNotLoadedException if zip extension not loaded
*/
public function __construct($options = null)
{
if (! extension_loaded('zip')) {
throw new Exception\ExtensionNotLoadedException('This filter needs the zip extension');
}
parent::__construct($options);
}
/**
* Returns the set archive
*
* @return string
*/
public function getArchive()
{
return $this->options['archive'];
}
/**
* Sets the archive to use for de-/compression
*
* @param string $archive Archive to use
* @return self
*/
public function setArchive($archive)
{
$archive = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, (string) $archive);
$this->options['archive'] = $archive;
return $this;
}
/**
* Returns the set targetpath
*
* @return string
*/
public function getTarget()
{
return $this->options['target'];
}
/**
* Sets the target to use
*
* @param string $target
* @throws Exception\InvalidArgumentException
* @return self
*/
public function setTarget($target)
{
if (! file_exists(dirname($target))) {
throw new Exception\InvalidArgumentException("The directory '$target' does not exist");
}
$target = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, (string) $target);
$this->options['target'] = $target;
return $this;
}
/**
* Compresses the given content
*
* @param string $content
* @return string Compressed archive
* @throws Exception\RuntimeException if unable to open zip archive, or error during compression
*/
public function compress($content)
{
$zip = new ZipArchive();
$res = $zip->open($this->getArchive(), ZipArchive::CREATE | ZipArchive::OVERWRITE);
if ($res !== true) {
throw new Exception\RuntimeException($this->errorString($res));
}
if (file_exists($content)) {
$content = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, realpath($content));
$basename = substr($content, strrpos($content, DIRECTORY_SEPARATOR) + 1);
if (is_dir($content)) {
$index = strrpos($content, DIRECTORY_SEPARATOR) + 1;
$content .= DIRECTORY_SEPARATOR;
$stack = [$content];
while (! empty($stack)) {
$current = array_pop($stack);
$files = [];
$dir = dir($current);
while (false !== ($node = $dir->read())) {
if ($node === '.' || $node === '..') {
continue;
}
if (is_dir($current . $node)) {
$stack[] = $current . $node . DIRECTORY_SEPARATOR;
}
if (is_file($current . $node)) {
$files[] = $node;
}
}
$local = substr($current, $index);
$zip->addEmptyDir(substr($local, 0, -1));
foreach ($files as $file) {
$zip->addFile($current . $file, $local . $file);
if ($res !== true) {
throw new Exception\RuntimeException($this->errorString($res));
}
}
}
} else {
$res = $zip->addFile($content, $basename);
if ($res !== true) {
throw new Exception\RuntimeException($this->errorString($res));
}
}
} else {
$file = $this->getTarget();
if (! is_dir($file)) {
$file = basename($file);
} else {
$file = 'zip.tmp';
}
$res = $zip->addFromString($file, $content);
if ($res !== true) {
throw new Exception\RuntimeException($this->errorString($res));
}
}
$zip->close();
return $this->options['archive'];
}
/**
* Decompresses the given content
*
* @param string $content
* @return string
* @throws Exception\RuntimeException If archive file not found, target directory not found,
* or error during decompression
*/
public function decompress($content)
{
$archive = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, realpath($content));
if (empty($archive) || ! file_exists($archive)) {
throw new Exception\RuntimeException('ZIP Archive not found');
}
$zip = new ZipArchive();
$res = $zip->open($archive);
$target = $this->getTarget();
if (! empty($target) && ! is_dir($target)) {
$target = dirname($target);
}
if (! empty($target)) {
$target = rtrim($target, '/\\') . DIRECTORY_SEPARATOR;
}
if (empty($target) || ! is_dir($target)) {
throw new Exception\RuntimeException('No target for ZIP decompression set');
}
if ($res !== true) {
throw new Exception\RuntimeException($this->errorString($res));
}
$res = $zip->extractTo($target);
if ($res !== true) {
throw new Exception\RuntimeException($this->errorString($res));
}
$zip->close();
return $target;
}
/**
* Returns the proper string based on the given error constant
*
* @param string $error
* @return string
*/
public function errorString($error)
{
switch ($error) {
case ZipArchive::ER_MULTIDISK:
return 'Multidisk ZIP Archives not supported';
case ZipArchive::ER_RENAME:
return 'Failed to rename the temporary file for ZIP';
case ZipArchive::ER_CLOSE:
return 'Failed to close the ZIP Archive';
case ZipArchive::ER_SEEK:
return 'Failure while seeking the ZIP Archive';
case ZipArchive::ER_READ:
return 'Failure while reading the ZIP Archive';
case ZipArchive::ER_WRITE:
return 'Failure while writing the ZIP Archive';
case ZipArchive::ER_CRC:
return 'CRC failure within the ZIP Archive';
case ZipArchive::ER_ZIPCLOSED:
return 'ZIP Archive already closed';
case ZipArchive::ER_NOENT:
return 'No such file within the ZIP Archive';
case ZipArchive::ER_EXISTS:
return 'ZIP Archive already exists';
case ZipArchive::ER_OPEN:
return 'Can not open ZIP Archive';
case ZipArchive::ER_TMPOPEN:
return 'Failure creating temporary ZIP Archive';
case ZipArchive::ER_ZLIB:
return 'ZLib Problem';
case ZipArchive::ER_MEMORY:
return 'Memory allocation problem while working on a ZIP Archive';
case ZipArchive::ER_CHANGED:
return 'ZIP Entry has been changed';
case ZipArchive::ER_COMPNOTSUPP:
return 'Compression method not supported within ZLib';
case ZipArchive::ER_EOF:
return 'Premature EOF within ZIP Archive';
case ZipArchive::ER_INVAL:
return 'Invalid argument for ZLIB';
case ZipArchive::ER_NOZIP:
return 'Given file is no zip archive';
case ZipArchive::ER_INTERNAL:
return 'Internal error while working on a ZIP Archive';
case ZipArchive::ER_INCONS:
return 'Inconsistent ZIP archive';
case ZipArchive::ER_REMOVE:
return 'Can not remove ZIP Archive';
case ZipArchive::ER_DELETED:
return 'ZIP Entry has been deleted';
default:
return 'Unknown error within ZIP Archive';
}
}
/**
* Returns the adapter name
*
* @return string
*/
public function toString()
{
return 'Zip';
}
}
================================================
FILE: src/Zend/Filter/src/Compress.php
================================================
setAdapter($options);
} elseif ($options instanceof Compress\CompressionAlgorithmInterface) {
$this->setAdapter($options);
} elseif (is_array($options)) {
$this->setOptions($options);
}
}
/**
* Set filter setate
*
* @param array $options
* @throws Exception\InvalidArgumentException if options is not an array or Traversable
* @return self
*/
public function setOptions($options)
{
if (! is_array($options) && ! $options instanceof Traversable) {
throw new Exception\InvalidArgumentException(sprintf(
'"%s" expects an array or Traversable; received "%s"',
__METHOD__,
(is_object($options) ? get_class($options) : gettype($options))
));
}
foreach ($options as $key => $value) {
if ($key === 'options') {
$key = 'adapterOptions';
}
$method = 'set' . ucfirst($key);
if (method_exists($this, $method)) {
$this->$method($value);
}
}
return $this;
}
/**
* Returns the current adapter, instantiating it if necessary
*
* @throws Exception\RuntimeException
* @throws Exception\InvalidArgumentException
* @return Compress\CompressionAlgorithmInterface
*/
public function getAdapter()
{
if ($this->adapter instanceof Compress\CompressionAlgorithmInterface) {
return $this->adapter;
}
$adapter = $this->adapter;
$options = $this->getAdapterOptions();
if (! class_exists($adapter)) {
$adapter = 'Zend\\Filter\\Compress\\' . ucfirst($adapter);
if (! class_exists($adapter)) {
throw new Exception\RuntimeException(sprintf(
'%s unable to load adapter; class "%s" not found',
__METHOD__,
$this->adapter
));
}
}
$this->adapter = new $adapter($options);
if (! $this->adapter instanceof Compress\CompressionAlgorithmInterface) {
throw new Exception\InvalidArgumentException(
"Compression adapter '" . $adapter
. "' does not implement Zend\\Filter\\Compress\\CompressionAlgorithmInterface"
);
}
return $this->adapter;
}
/**
* Retrieve adapter name
*
* @return string
*/
public function getAdapterName()
{
return $this->getAdapter()->toString();
}
/**
* Sets compression adapter
*
* @param string|Compress\CompressionAlgorithmInterface $adapter Adapter to use
* @return self
* @throws Exception\InvalidArgumentException
*/
public function setAdapter($adapter)
{
if ($adapter instanceof Compress\CompressionAlgorithmInterface) {
$this->adapter = $adapter;
return $this;
}
if (! is_string($adapter)) {
throw new Exception\InvalidArgumentException(
'Invalid adapter provided; must be string or instance of '
. 'Zend\\Filter\\Compress\\CompressionAlgorithmInterface'
);
}
$this->adapter = $adapter;
return $this;
}
/**
* Retrieve adapter options
*
* @return array
*/
public function getAdapterOptions()
{
return $this->adapterOptions;
}
/**
* Set adapter options
*
* @param array $options
* @return self
*/
public function setAdapterOptions(array $options)
{
$this->adapterOptions = $options;
return $this;
}
/**
* Get individual or all options from underlying adapter
*
* @param null|string $option
* @return mixed
*/
public function getOptions($option = null)
{
$adapter = $this->getAdapter();
return $adapter->getOptions($option);
}
/**
* Calls adapter methods
*
* @param string $method Method to call
* @param string|array $options Options for this method
* @return mixed
* @throws Exception\BadMethodCallException
*/
public function __call($method, $options)
{
$adapter = $this->getAdapter();
if (! method_exists($adapter, $method)) {
throw new Exception\BadMethodCallException("Unknown method '{$method}'");
}
return call_user_func_array([$adapter, $method], $options);
}
/**
* Defined by Zend\Filter\FilterInterface
*
* Compresses the content $value with the defined settings
*
* @param string $value Content to compress
* @return string The compressed content
*/
public function filter($value)
{
if (! is_string($value)) {
return $value;
}
return $this->getAdapter()->compress($value);
}
}
================================================
FILE: src/Zend/Filter/src/ConfigProvider.php
================================================
$this->getDependencyConfig(),
];
}
/**
* Return dependency mappings for this component.
*
* @return array
*/
public function getDependencyConfig()
{
return [
'aliases' => [
'FilterManager' => FilterPluginManager::class,
],
'factories' => [
FilterPluginManager::class => FilterPluginManagerFactory::class,
],
];
}
}
================================================
FILE: src/Zend/Filter/src/DataUnitFormatter.php
================================================
['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi', 'Yi'],
// decimal SI units:
self::MODE_DECIMAL => ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'],
];
/**
* Default options:
*
* @var array
*/
protected $options = [
'mode' => self::MODE_DECIMAL,
'unit' => '',
'precision' => 2,
'prefixes' => [],
];
/**
* @param array $options
*/
public function __construct($options = [])
{
if (! static::isOptions($options)) {
throw new InvalidArgumentException('The unit filter needs options to work.');
}
if (! isset($options['unit'])) {
throw new InvalidArgumentException('The unit filter needs a unit to work with.');
}
$this->setOptions($options);
}
/**
* Define the mode of the filter. Possible values can be fount at self::$modes.
*
* @param string $mode
*
* @throws InvalidArgumentException
*/
protected function setMode($mode)
{
$mode = strtolower($mode);
if (! in_array($mode, self::$modes, true)) {
throw new InvalidArgumentException(sprintf('Invalid binary mode: %s', $mode));
}
$this->options['mode'] = $mode;
}
/**
* Get current filter mode
*
* @return string
*/
protected function getMode()
{
return $this->options['mode'];
}
/**
* Find out if the filter is in decimal mode.
*
* @return bool
*/
protected function isDecimalMode()
{
return $this->getMode() === self::MODE_DECIMAL;
}
/**
* Find out if the filter is in binary mode.
*
* @return bool
*/
protected function isBinaryMode()
{
return $this->getMode() === self::MODE_BINARY;
}
/**
* Define the unit of the filter. Possible values can be fount at self::$types.
*
* @param string $unit
*/
protected function setUnit($unit)
{
$this->options['unit'] = (string) $unit;
}
/**
* Get current filter type
*
* @return string
*/
protected function getUnit()
{
return $this->options['unit'];
}
/**
* Set the precision of the filtered result.
*
* @param $precision
*/
protected function setPrecision($precision)
{
$this->options['precision'] = (int) $precision;
}
/**
* Get the precision of the filtered result.
*
* @return int
*/
protected function getPrecision()
{
return $this->options['precision'];
}
/**
* Set the precision of the result.
*
* @param array $prefixes
*/
protected function setPrefixes(array $prefixes)
{
$this->options['prefixes'] = $prefixes;
}
/**
* Get the predefined prefixes or use the build-in standardized lists of prefixes.
*
* @return array
*/
protected function getPrefixes()
{
$prefixes = $this->options['prefixes'];
if ($prefixes) {
return $prefixes;
}
return self::$standardizedPrefixes[$this->getMode()];
}
/**
* Find the prefix at a specific location in the prefixes array.
*
* @param $index
*
* @return string|null
*/
protected function getPrefixAt($index)
{
$prefixes = $this->getPrefixes();
return $prefixes[$index] ?? null;
}
/**
* Defined by Zend\Filter\FilterInterface
*
* Returns a human readable format of the amount of bits or bytes.
*
* If the value provided is not numeric, the value will remain unfiltered
*
* @param string $value
* @return string|mixed
*/
public function filter($value)
{
if (! is_numeric($value)) {
return $value;
}
// Parse to float and check if value is not zero
$amount = (float) $value;
if ($amount === 0.0) {
return $this->formatAmount($amount);
}
// Calculate the correct size and prefix:
$base = $this->isBinaryMode() ? self::BASE_BINARY : self::BASE_DECIMAL;
$power = floor(log($amount, $base));
$prefix = $this->getPrefixAt((int)$power);
// When the amount is too big, no prefix can be found:
if ($prefix === null) {
return $this->formatAmount($amount);
}
// return formatted value:
$result = ($amount / pow($base, $power));
$formatted = number_format($result, $this->getPrecision());
return $this->formatAmount($formatted, $prefix);
}
/**
* @param $amount
* @param null $prefix
*
* @return string
*/
protected function formatAmount($amount, $prefix = null)
{
return sprintf('%s %s%s', $amount, $prefix, $this->getUnit());
}
}
================================================
FILE: src/Zend/Filter/src/DateSelect.php
================================================
setOptions($options);
}
}
/**
* Set the format string accepted by date() to use when formatting a string
*
* @param string $format
* @return self
*/
public function setFormat($format)
{
$this->format = $format;
return $this;
}
/**
* Filter a datetime string by normalizing it to the filters specified format
*
* @param DateTime|string|integer $value
* @throws Exception\InvalidArgumentException
* @return string
*/
public function filter($value)
{
try {
$result = $this->normalizeDateTime($value);
} catch (\Exception $e) {
// DateTime threw an exception, an invalid date string was provided
throw new Exception\InvalidArgumentException('Invalid date string provided', $e->getCode(), $e);
}
if ($result === false) {
return $value;
}
return $result;
}
/**
* Normalize the provided value to a formatted string
*
* @param string|int|DateTime $value
* @return string
*/
protected function normalizeDateTime($value)
{
if ($value === '' || $value === null) {
return $value;
}
if (! is_string($value) && ! is_int($value) && ! $value instanceof DateTime) {
return $value;
}
if (is_int($value)) {
//timestamp
$value = new DateTime('@' . $value);
} elseif (! $value instanceof DateTime) {
$value = new DateTime($value);
}
return $value->format($this->format);
}
}
================================================
FILE: src/Zend/Filter/src/DateTimeSelect.php
================================================
isNullOnEmpty()
&& (
empty($value['year'])
|| empty($value['month'])
|| empty($value['day'])
|| empty($value['hour'])
|| empty($value['minute'])
|| (isset($value['second']) && empty($value['second']))
)
) {
return;
}
if ($this->isNullOnAllEmpty()
&& (
empty($value['year'])
&& empty($value['month'])
&& empty($value['day'])
&& empty($value['hour'])
&& empty($value['minute'])
&& (! isset($value['second']) || empty($value['second']))
)
) {
// Cannot handle this value
return;
}
if (! isset($value['second'])) {
$value['second'] = '00';
}
$this->filterable($value);
ksort($value);
$value = vsprintf($this->format, $value);
return $value;
}
}
================================================
FILE: src/Zend/Filter/src/Decompress.php
================================================
filter($value);
}
/**
* Defined by FilterInterface
*
* Decompresses the content $value with the defined settings
*
* @param string $value Content to decompress
* @return string The decompressed content
*/
public function filter($value)
{
if (! is_string($value) && $value !== null) {
return $value;
}
return $this->getAdapter()->decompress($value);
}
}
================================================
FILE: src/Zend/Filter/src/Decrypt.php
================================================
adapter->decrypt($value);
}
}
================================================
FILE: src/Zend/Filter/src/Digits.php
================================================
encryption key string
* 'key_iteration' => the number of iterations for the PBKDF2 key generation
* 'algorithm => cipher algorithm to use
* 'hash' => algorithm to use for the authentication
* 'vector' => initialization vector
* )
*/
protected $encryption = [
'key_iteration' => 5000,
'algorithm' => 'aes',
'hash' => 'sha256',
];
/**
* BlockCipher
*
* @var BlockCipher
*/
protected $blockCipher;
/**
* Internal compression
*
* @var array
*/
protected $compression;
/**
* Class constructor
*
* @param string|array|Traversable $options Encryption Options
* @throws Exception\RuntimeException
* @throws Exception\InvalidArgumentException
*/
public function __construct($options)
{
$cipherPluginManager = CryptBlockCipher::getSymmetricPluginManager();
$cipherType = $cipherPluginManager->has('openssl') ? 'openssl' : 'mcrypt';
try {
$this->blockCipher = CryptBlockCipher::factory($cipherType, $this->encryption);
} catch (SymmetricException\RuntimeException) {
throw new Exception\RuntimeException(sprintf(
'The BlockCipher cannot be used without the %s extension',
$cipherType
));
}
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
} elseif (is_string($options)) {
$options = ['key' => $options];
} elseif (! is_array($options)) {
throw new Exception\InvalidArgumentException('Invalid options argument provided to filter');
}
if (array_key_exists('compression', $options)) {
$this->setCompression($options['compression']);
unset($options['compress']);
}
$this->setEncryption($options);
}
/**
* Returns the set encryption options
*
* @return array
*/
public function getEncryption()
{
return $this->encryption;
}
/**
* Sets new encryption options
*
* @param string|array $options Encryption options
* @return self
* @throws Exception\InvalidArgumentException
*/
public function setEncryption($options)
{
if (is_string($options)) {
$this->blockCipher->setKey($options);
$this->encryption['key'] = $options;
return $this;
}
if (! is_array($options)) {
throw new Exception\InvalidArgumentException('Invalid options argument provided to filter');
}
$options += $this->encryption;
if (isset($options['key'])) {
$this->blockCipher->setKey($options['key']);
}
if (isset($options['algorithm'])) {
try {
$this->blockCipher->setCipherAlgorithm($options['algorithm']);
} catch (CryptException\InvalidArgumentException) {
throw new Exception\InvalidArgumentException(
"The algorithm '{$options['algorithm']}' is not supported"
);
}
}
if (isset($options['hash'])) {
try {
$this->blockCipher->setHashAlgorithm($options['hash']);
} catch (CryptException\InvalidArgumentException) {
throw new Exception\InvalidArgumentException("The algorithm '{$options['hash']}' is not supported");
}
}
if (isset($options['vector'])) {
$this->setVector($options['vector']);
}
if (isset($options['key_iteration'])) {
$this->blockCipher->setKeyIteration($options['key_iteration']);
}
$this->encryption = $options;
return $this;
}
/**
* Returns the initialization vector
*
* @return string
*/
public function getVector()
{
return $this->encryption['vector'];
}
/**
* Set the inizialization vector
*
* @param string $vector
* @return self
* @throws Exception\InvalidArgumentException
*/
public function setVector($vector)
{
try {
$this->blockCipher->setSalt($vector);
} catch (CryptException\InvalidArgumentException $e) {
throw new Exception\InvalidArgumentException($e->getMessage());
}
$this->encryption['vector'] = $vector;
return $this;
}
/**
* Set the encryption key
*
* @param string $key
* @return self
* @throws Exception\InvalidArgumentException
*/
public function setKey($key)
{
try {
$this->blockCipher->setKey($key);
} catch (CryptException\InvalidArgumentException $e) {
throw new Exception\InvalidArgumentException($e->getMessage());
}
$this->encryption['key'] = $key;
return $this;
}
/**
* Get the encryption key
*
* @return string
*/
public function getKey()
{
return $this->encryption['key'];
}
/**
* Returns the compression
*
* @return array
*/
public function getCompression()
{
return $this->compression;
}
/**
* Sets an internal compression for values to encrypt
*
* @param string|array $compression
* @return self
*/
public function setCompression($compression)
{
if (is_string($this->compression)) {
$compression = ['adapter' => $compression];
}
$this->compression = $compression;
return $this;
}
/**
* Defined by Zend\Filter\FilterInterface
*
* Encrypts $value with the defined settings
*
* @param string $value The content to encrypt
* @throws Exception\InvalidArgumentException
* @return string The encrypted content
*/
public function encrypt($value)
{
// compress prior to encryption
if (! empty($this->compression)) {
$compress = new Compress($this->compression);
$value = $compress($value);
}
try {
$encrypted = $this->blockCipher->encrypt($value);
} catch (CryptException\InvalidArgumentException $e) {
throw new Exception\InvalidArgumentException($e->getMessage());
}
return $encrypted;
}
/**
* Defined by Zend\Filter\FilterInterface
*
* Decrypts $value with the defined settings
*
* @param string $value Content to decrypt
* @return string The decrypted content
*/
public function decrypt($value)
{
$decrypted = $this->blockCipher->decrypt($value);
// decompress after decryption
if (! empty($this->compression)) {
$decompress = new Decompress($this->compression);
$decrypted = $decompress($decrypted);
}
return $decrypted;
}
/**
* Returns the adapter name
*
* @return string
*/
public function toString()
{
return 'BlockCipher';
}
}
================================================
FILE: src/Zend/Filter/src/Encrypt/EncryptionAlgorithmInterface.php
================================================
public keys
* 'private' => private keys
* 'envelope' => resulting envelope keys
* )
*/
protected $keys = [
'public' => [],
'private' => [],
'envelope' => [],
];
/**
* Internal passphrase
*
* @var string
*/
protected $passphrase;
/**
* Internal compression
*
* @var array
*/
protected $compression;
/**
* Internal create package
*
* @var bool
*/
protected $package = false;
/**
* Class constructor
* Available options
* 'public' => public key
* 'private' => private key
* 'envelope' => envelope key
* 'passphrase' => passphrase
* 'compression' => compress value with this compression adapter
* 'package' => pack envelope keys into encrypted string, simplifies decryption
*
* @param string|array|Traversable $options Options for this adapter
* @throws Exception\ExtensionNotLoadedException
*/
public function __construct($options = [])
{
if (! extension_loaded('openssl')) {
throw new Exception\ExtensionNotLoadedException('This filter needs the openssl extension');
}
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
}
if (! is_array($options)) {
$options = ['public' => $options];
}
if (array_key_exists('passphrase', $options)) {
$this->setPassphrase($options['passphrase']);
unset($options['passphrase']);
}
if (array_key_exists('compression', $options)) {
$this->setCompression($options['compression']);
unset($options['compression']);
}
if (array_key_exists('package', $options)) {
$this->setPackage($options['package']);
unset($options['package']);
}
$this->_setKeys($options);
}
/**
* Sets the encryption keys
*
* @param string|array $keys Key with type association
* @return self
* @throws Exception\InvalidArgumentException
*/
// @codingStandardsIgnoreStart
protected function _setKeys($keys)
{
// @codingStandardsIgnoreEnd
if (! is_array($keys)) {
throw new Exception\InvalidArgumentException('Invalid options argument provided to filter');
}
foreach ($keys as $type => $key) {
if (is_file($key) && is_readable($key)) {
$file = fopen($key, 'r');
$cert = fread($file, 8192);
fclose($file);
} else {
$cert = $key;
$key = count($this->keys[$type]);
}
switch ($type) {
case 'public':
$test = openssl_pkey_get_public($cert);
if ($test === false) {
throw new Exception\InvalidArgumentException("Public key '{$cert}' not valid");
}
openssl_free_key($test);
$this->keys['public'][$key] = $cert;
break;
case 'private':
$test = openssl_pkey_get_private($cert, $this->passphrase);
if ($test === false) {
throw new Exception\InvalidArgumentException("Private key '{$cert}' not valid");
}
openssl_free_key($test);
$this->keys['private'][$key] = $cert;
break;
case 'envelope':
$this->keys['envelope'][$key] = $cert;
break;
default:
break;
}
}
return $this;
}
/**
* Returns all public keys
*
* @return array
*/
public function getPublicKey()
{
return $this->keys['public'];
}
/**
* Sets public keys
*
* @param string|array $key Public keys
* @return self
*/
public function setPublicKey($key)
{
if (is_array($key)) {
foreach ($key as $type => $option) {
if ($type !== 'public') {
$key['public'] = $option;
unset($key[$type]);
}
}
} else {
$key = ['public' => $key];
}
return $this->_setKeys($key);
}
/**
* Returns all private keys
*
* @return array
*/
public function getPrivateKey()
{
return $this->keys['private'];
}
/**
* Sets private keys
*
* @param string|array $key Private key
* @param string|null $passphrase
* @return self
*/
public function setPrivateKey($key, $passphrase = null)
{
if (is_array($key)) {
foreach ($key as $type => $option) {
if ($type !== 'private') {
$key['private'] = $option;
unset($key[$type]);
}
}
} else {
$key = ['private' => $key];
}
if ($passphrase !== null) {
$this->setPassphrase($passphrase);
}
return $this->_setKeys($key);
}
/**
* Returns all envelope keys
*
* @return array
*/
public function getEnvelopeKey()
{
return $this->keys['envelope'];
}
/**
* Sets envelope keys
*
* @param string|array $key Envelope keys
* @return self
*/
public function setEnvelopeKey($key)
{
if (is_array($key)) {
foreach ($key as $type => $option) {
if ($type !== 'envelope') {
$key['envelope'] = $option;
unset($key[$type]);
}
}
} else {
$key = ['envelope' => $key];
}
return $this->_setKeys($key);
}
/**
* Returns the passphrase
*
* @return string
*/
public function getPassphrase()
{
return $this->passphrase;
}
/**
* Sets a new passphrase
*
* @param string $passphrase
* @return self
*/
public function setPassphrase($passphrase)
{
$this->passphrase = $passphrase;
return $this;
}
/**
* Returns the compression
*
* @return array
*/
public function getCompression()
{
return $this->compression;
}
/**
* Sets an internal compression for values to encrypt
*
* @param string|array $compression
* @return self
*/
public function setCompression($compression)
{
if (is_string($this->compression)) {
$compression = ['adapter' => $compression];
}
$this->compression = $compression;
return $this;
}
/**
* Returns if header should be packaged
*
* @return bool
*/
public function getPackage()
{
return $this->package;
}
/**
* Sets if the envelope keys should be included in the encrypted value
*
* @param bool $package
* @return self
*/
public function setPackage($package)
{
$this->package = (bool) $package;
return $this;
}
/**
* Encrypts $value with the defined settings
* Note that you also need the "encrypted" keys to be able to decrypt
*
* @param string $value Content to encrypt
* @return string The encrypted content
* @throws Exception\RuntimeException
*/
public function encrypt($value)
{
$encrypted = [];
$encryptedkeys = [];
if (! $this->keys['public']) {
throw new Exception\RuntimeException('Openssl can not encrypt without public keys');
}
$keys = [];
$fingerprints = [];
$count = -1;
foreach ($this->keys['public'] as $key => $cert) {
$keys[$key] = openssl_pkey_get_public($cert);
if ($this->package) {
$details = openssl_pkey_get_details($keys[$key]);
if ($details === false) {
$details = ['key' => 'ZendFramework'];
}
++$count;
$fingerprints[$count] = md5($details['key']);
}
}
// compress prior to encryption
if (! empty($this->compression)) {
$compress = new Compress($this->compression);
$value = $compress($value);
}
$crypt = openssl_seal($value, $encrypted, $encryptedkeys, $keys);
foreach ($keys as $key) {
openssl_free_key($key);
}
if ($crypt === false) {
throw new Exception\RuntimeException('Openssl was not able to encrypt your content with the given options');
}
$this->keys['envelope'] = $encryptedkeys;
// Pack data and envelope keys into single string
if ($this->package) {
$header = pack('n', count($this->keys['envelope']));
foreach ($this->keys['envelope'] as $key => $envKey) {
$header .= pack('H32n', $fingerprints[$key], strlen($envKey)) . $envKey;
}
$encrypted = $header . $encrypted;
}
return $encrypted;
}
/**
* Defined by Zend\Filter\FilterInterface
*
* Decrypts $value with the defined settings
*
* @param string $value Content to decrypt
* @return string The decrypted content
* @throws Exception\RuntimeException
*/
public function decrypt($value)
{
$decrypted = '';
$envelope = current($this->getEnvelopeKey());
if (count($this->keys['private']) !== 1) {
throw new Exception\RuntimeException('Please give a private key for decryption with Openssl');
}
if (! $this->package && empty($envelope)) {
throw new Exception\RuntimeException('Please give an envelope key for decryption with Openssl');
}
foreach ($this->keys['private'] as $cert) {
$keys = openssl_pkey_get_private($cert, $this->getPassphrase());
}
if ($this->package) {
$details = openssl_pkey_get_details($keys);
if ($details !== false) {
$fingerprint = md5($details['key']);
} else {
$fingerprint = md5("ZendFramework");
}
$count = unpack('ncount', $value);
$count = $count['count'];
$length = 2;
for ($i = $count; $i > 0; --$i) {
$header = unpack('H32print/nsize', substr($value, $length, 18));
$length += 18;
if ($header['print'] === $fingerprint) {
$envelope = substr($value, $length, $header['size']);
}
$length += $header['size'];
}
// remainder of string is the value to decrypt
$value = substr($value, $length);
}
$crypt = openssl_open($value, $decrypted, $envelope, $keys);
openssl_free_key($keys);
if ($crypt === false) {
throw new Exception\RuntimeException('Openssl was not able to decrypt you content with the given options');
}
// decompress after decryption
if (! empty($this->compression)) {
$decompress = new Decompress($this->compression);
$decrypted = $decompress($decrypted);
}
return $decrypted;
}
/**
* Returns the adapter name
*
* @return string
*/
public function toString()
{
return 'Openssl';
}
}
================================================
FILE: src/Zend/Filter/src/Encrypt.php
================================================
setAdapter($options);
}
/**
* Returns the adapter instance
*
* @throws Exception\RuntimeException
* @throws Exception\InvalidArgumentException
* @return Encrypt\EncryptionAlgorithmInterface
*/
public function getAdapterInstance()
{
if ($this->adapter instanceof Encrypt\EncryptionAlgorithmInterface) {
return $this->adapter;
}
$adapter = $this->adapter;
$options = $this->getOptions();
if (! class_exists($adapter)) {
$adapter = __CLASS__ . '\\' . ucfirst($adapter);
if (! class_exists($adapter)) {
throw new Exception\RuntimeException(sprintf(
'%s unable to load adapter; class "%s" not found',
__METHOD__,
$this->adapter
));
}
}
$this->adapter = new $adapter($options);
if (! $this->adapter instanceof Encrypt\EncryptionAlgorithmInterface) {
throw new Exception\InvalidArgumentException(sprintf(
'Encryption adapter "%s" does not implement %s\\EncryptionAlgorithmInterface',
$adapter,
__CLASS__
));
}
return $this->adapter;
}
/**
* Returns the name of the set adapter
*
* @return string
*/
public function getAdapter()
{
return $this->adapter->toString();
}
/**
* Sets new encryption options
*
* @param string|array $options (Optional) Encryption options
* @return self
* @throws Exception\DomainException
* @throws Exception\InvalidArgumentException
*/
public function setAdapter($options = null)
{
if (is_string($options)) {
$adapter = $options;
} elseif (isset($options['adapter'])) {
$adapter = $options['adapter'];
unset($options['adapter']);
} else {
$adapter = 'BlockCipher';
}
if (! is_array($options)) {
$options = [];
}
if (class_exists('Zend\Filter\Encrypt\\' . ucfirst($adapter))) {
$adapter = 'Zend\Filter\Encrypt\\' . ucfirst($adapter);
} elseif (! class_exists($adapter)) {
throw new Exception\DomainException(
sprintf(
'%s expects a valid registry class name; received "%s", which did not resolve',
__METHOD__,
$adapter
)
);
}
$this->adapter = new $adapter($options);
if (! $this->adapter instanceof Encrypt\EncryptionAlgorithmInterface) {
throw new Exception\InvalidArgumentException(
"Encoding adapter '" . $adapter
. "' does not implement Zend\\Filter\\Encrypt\\EncryptionAlgorithmInterface"
);
}
return $this;
}
/**
* Calls adapter methods
*
* @param string $method Method to call
* @param string|array $options Options for this method
* @return mixed
* @throws Exception\BadMethodCallException
*/
public function __call($method, $options)
{
$part = substr($method, 0, 3);
if (($part !== 'get' && $part !== 'set') || ! method_exists($this->adapter, $method)) {
throw new Exception\BadMethodCallException("Unknown method '{$method}'");
}
return call_user_func_array([$this->adapter, $method], $options);
}
/**
* Defined by Zend\Filter\Filter
*
* Encrypts the content $value with the defined settings
*
* @param string $value Content to encrypt
* @return string The encrypted content
*/
public function filter($value)
{
if (! is_string($value) && ! is_numeric($value)) {
return $value;
}
return $this->adapter->encrypt($value);
}
}
================================================
FILE: src/Zend/Filter/src/Exception/BadMethodCallException.php
================================================
filename;
}
/**
* Sets the new filename where the content will be stored
*
* @param string $filename (Optional) New filename to set
* @return self
*/
public function setFilename($filename = null)
{
$this->filename = $filename;
return $this;
}
/**
* Defined by Zend\Filter\FilterInterface
*
* Decrypts the file $value with the defined settings
*
* @param string|array $value Full path of file to change or $_FILES data array
* @return string|array The filename which has been set
* @throws Exception\InvalidArgumentException
* @throws Exception\RuntimeException
*/
public function filter($value)
{
if (! is_scalar($value) && ! is_array($value)) {
return $value;
}
// An uploaded file? Retrieve the 'tmp_name'
$isFileUpload = false;
if (is_array($value)) {
if (! isset($value['tmp_name'])) {
return $value;
}
$isFileUpload = true;
$uploadData = $value;
$value = $value['tmp_name'];
}
if (! file_exists($value)) {
throw new Exception\InvalidArgumentException("File '$value' not found");
}
if (! isset($this->filename)) {
$this->filename = $value;
}
if (file_exists($this->filename) && ! is_writable($this->filename)) {
throw new Exception\RuntimeException("File '{$this->filename}' is not writable");
}
$content = file_get_contents($value);
if (! $content) {
throw new Exception\RuntimeException("Problem while reading file '$value'");
}
$decrypted = parent::filter($content);
$result = file_put_contents($this->filename, $decrypted);
if (! $result) {
throw new Exception\RuntimeException("Problem while writing file '{$this->filename}'");
}
if ($isFileUpload) {
$uploadData['tmp_name'] = $this->filename;
return $uploadData;
}
return $this->filename;
}
}
================================================
FILE: src/Zend/Filter/src/File/Encrypt.php
================================================
filename;
}
/**
* Sets the new filename where the content will be stored
*
* @param string $filename (Optional) New filename to set
* @return self
*/
public function setFilename($filename = null)
{
$this->filename = $filename;
return $this;
}
/**
* Defined by Zend\Filter\Filter
*
* Encrypts the file $value with the defined settings
*
* @param string|array $value Full path of file to change or $_FILES data array
* @return string|array The filename which has been set, or false when there were errors
* @throws Exception\InvalidArgumentException
* @throws Exception\RuntimeException
*/
public function filter($value)
{
if (! is_scalar($value) && ! is_array($value)) {
return $value;
}
// An uploaded file? Retrieve the 'tmp_name'
$isFileUpload = false;
if (is_array($value)) {
if (! isset($value['tmp_name'])) {
return $value;
}
$isFileUpload = true;
$uploadData = $value;
$value = $value['tmp_name'];
}
if (! file_exists($value)) {
throw new Exception\InvalidArgumentException("File '$value' not found");
}
if (! isset($this->filename)) {
$this->filename = $value;
}
if (file_exists($this->filename) && ! is_writable($this->filename)) {
throw new Exception\RuntimeException("File '{$this->filename}' is not writable");
}
$content = file_get_contents($value);
if (! $content) {
throw new Exception\RuntimeException("Problem while reading file '$value'");
}
$encrypted = parent::filter($content);
$result = file_put_contents($this->filename, $encrypted);
if (! $result) {
throw new Exception\RuntimeException("Problem while writing file '{$this->filename}'");
}
if ($isFileUpload) {
$uploadData['tmp_name'] = $this->filename;
return $uploadData;
}
return $this->filename;
}
}
================================================
FILE: src/Zend/Filter/src/File/LowerCase.php
================================================
Source filename or directory which will be renamed
* 'target' => Target filename or directory, the new name of the source file
* 'overwrite' => Shall existing files be overwritten ?
* 'randomize' => Shall target files have a random postfix attached?
*
* @param string|array|Traversable $options Target file or directory to be renamed
* @throws Exception\InvalidArgumentException
*/
public function __construct($options = [])
{
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
} elseif (is_string($options)) {
$options = ['target' => $options];
} elseif (! is_array($options)) {
throw new Exception\InvalidArgumentException(
'Invalid options argument provided to filter'
);
}
$this->setFile($options);
}
/**
* Returns the files to rename and their new name and location
*
* @return array
*/
public function getFile()
{
return $this->files;
}
/**
* Sets a new file or directory as target, deleting existing ones
*
* Array accepts the following keys:
* 'source' => Source filename or directory which will be renamed
* 'target' => Target filename or directory, the new name of the sourcefile
* 'overwrite' => Shall existing files be overwritten?
* 'randomize' => Shall target files have a random postfix attached?
*
* @param string|array $options Old file or directory to be rewritten
* @return self
*/
public function setFile($options)
{
$this->files = [];
$this->addFile($options);
return $this;
}
/**
* Adds a new file or directory as target to the existing ones
*
* Array accepts the following keys:
* 'source' => Source filename or directory which will be renamed
* 'target' => Target filename or directory, the new name of the sourcefile
* 'overwrite' => Shall existing files be overwritten?
* 'randomize' => Shall target files have a random postfix attached?
*
* @param string|array $options Old file or directory to be rewritten
* @return Rename
* @throws Exception\InvalidArgumentException
*/
public function addFile($options)
{
if (is_string($options)) {
$options = ['target' => $options];
} elseif (! is_array($options)) {
throw new Exception\InvalidArgumentException(
'Invalid options to rename filter provided'
);
}
$this->_convertOptions($options);
return $this;
}
/**
* Returns only the new filename without moving it
* But existing files will be erased when the overwrite option is true
*
* @param string $value Full path of file to change
* @param bool $source Return internal information
* @return string The new filename which has been set
* @throws Exception\InvalidArgumentException If the target file already exists.
*/
public function getNewName($value, $source = false)
{
$file = $this->_getFileName($value);
if (! is_array($file)) {
return $file;
}
if ($file['source'] === $file['target']) {
return $value;
}
if (! file_exists($file['source'])) {
return $value;
}
if ($file['overwrite'] && file_exists($file['target'])) {
unlink($file['target']);
}
if (file_exists($file['target'])) {
throw new Exception\InvalidArgumentException(sprintf(
'"File "%s" could not be renamed to "%s"; target file already exists',
$value,
realpath($file['target'])
));
}
if ($source) {
return $file;
}
return $file['target'];
}
/**
* Defined by Zend\Filter\Filter
*
* Renames the file $value to the new name set before
* Returns the file $value, removing all but digit characters
*
* @param string|array $value Full path of file to change or $_FILES data array
* @throws Exception\RuntimeException
* @return string|array The new filename which has been set
*/
public function filter($value)
{
if (! is_scalar($value) && ! is_array($value)) {
return $value;
}
// An uploaded file? Retrieve the 'tmp_name'
$isFileUpload = false;
if (is_array($value)) {
if (! isset($value['tmp_name'])) {
return $value;
}
$isFileUpload = true;
$uploadData = $value;
$value = $value['tmp_name'];
}
$file = $this->getNewName($value, true);
if (is_string($file)) {
if ($isFileUpload) {
return $uploadData;
} else {
return $file;
}
}
$result = rename($file['source'], $file['target']);
if ($result !== true) {
throw new Exception\RuntimeException(
sprintf(
"File '%s' could not be renamed. " .
"An error occurred while processing the file.",
$value
)
);
}
if ($isFileUpload) {
$uploadData['tmp_name'] = $file['target'];
return $uploadData;
}
return $file['target'];
}
/**
* Internal method for creating the file array
* Supports single and nested arrays
*
* @param array $options
* @return array
*/
// @codingStandardsIgnoreStart
protected function _convertOptions($options)
{
// @codingStandardsIgnoreEnd
$files = [];
foreach ($options as $key => $value) {
if (is_array($value)) {
$this->_convertOptions($value);
continue;
}
switch ($key) {
case "source":
$files['source'] = (string) $value;
break;
case 'target':
$files['target'] = (string) $value;
break;
case 'overwrite':
$files['overwrite'] = (bool) $value;
break;
case 'randomize':
$files['randomize'] = (bool) $value;
break;
default:
break;
}
}
if (empty($files)) {
return $this;
}
if (empty($files['source'])) {
$files['source'] = '*';
}
if (empty($files['target'])) {
$files['target'] = '*';
}
if (empty($files['overwrite'])) {
$files['overwrite'] = false;
}
if (empty($files['randomize'])) {
$files['randomize'] = false;
}
$found = false;
foreach ($this->files as $key => $value) {
if ($value['source'] === $files['source']) {
$this->files[$key] = $files;
$found = true;
}
}
if (! $found) {
$count = count($this->files);
$this->files[$count] = $files;
}
return $this;
}
/**
* Internal method to resolve the requested source
* and return all other related parameters
*
* @param string $file Filename to get the information for
* @return array|string
*/
// @codingStandardsIgnoreStart
protected function _getFileName($file)
{
// @codingStandardsIgnoreEnd
$rename = [];
foreach ($this->files as $value) {
if ($value['source'] === '*') {
if (! isset($rename['source'])) {
$rename = $value;
$rename['source'] = $file;
}
}
if ($value['source'] === $file) {
$rename = $value;
break;
}
}
if (! isset($rename['source'])) {
return $file;
}
if (! isset($rename['target']) || $rename['target'] === '*') {
$rename['target'] = $rename['source'];
}
if (is_dir($rename['target'])) {
$name = basename($rename['source']);
$last = $rename['target'][strlen($rename['target']) - 1];
if ($last !== '/' && $last !== '\\') {
$rename['target'] .= DIRECTORY_SEPARATOR;
}
$rename['target'] .= $name;
}
if ($rename['randomize']) {
$info = pathinfo($rename['target']);
$newTarget = $info['dirname'] . DIRECTORY_SEPARATOR .
$info['filename'] . uniqid('_', false);
if (isset($info['extension'])) {
$newTarget .= '.' . $info['extension'];
}
$rename['target'] = $newTarget;
}
return $rename;
}
}
================================================
FILE: src/Zend/Filter/src/File/RenameUpload.php
================================================
null,
'use_upload_name' => false,
'use_upload_extension' => false,
'overwrite' => false,
'randomize' => false,
'stream_factory' => null,
'upload_file_factory' => null,
];
/**
* Store already filtered values, so we can filter multiple
* times the same file without being block by move_uploaded_file
* internal checks
*
* @var array
*/
protected $alreadyFiltered = [];
/**
* Constructor
*
* @param array|string $targetOrOptions The target file path or an options array
*/
public function __construct($targetOrOptions = [])
{
if (is_array($targetOrOptions)) {
$this->setOptions($targetOrOptions);
} else {
$this->setTarget($targetOrOptions);
}
}
/**
* @param StreamFactoryInterface $factory Factory to use to produce a PSR-7
* stream with which to seed a PSR-7 UploadedFileInterface.
* @return self
*/
public function setStreamFactory(StreamFactoryInterface $factory)
{
$this->options['stream_factory'] = $factory;
return $this;
}
/**
* @return null|StreamFactoryInterface
*/
public function getStreamFactory()
{
return $this->options['stream_factory'];
}
/**
* @param string $target Target file path or directory
* @return self
*/
public function setTarget($target)
{
if (! is_string($target)) {
throw new Exception\InvalidArgumentException(
'Invalid target, must be a string'
);
}
$this->options['target'] = $target;
return $this;
}
/**
* @return string Target file path or directory
*/
public function getTarget()
{
return $this->options['target'];
}
/**
* @param UploadedFileFactoryInterface $factory Factory to use to produce
* filtered PSR-7 UploadedFileInterface instances.
* @return self
*/
public function setUploadFileFactory(UploadedFileFactoryInterface $factory)
{
$this->options['upload_file_factory'] = $factory;
return $this;
}
/**
* @return null|UploadedFileFactoryInterface
*/
public function getUploadFileFactory()
{
return $this->options['upload_file_factory'];
}
/**
* @param bool $flag When true, this filter will use the $_FILES['name']
* as the target filename.
* Otherwise, it uses the default 'target' rules.
* @return self
*/
public function setUseUploadName($flag = true)
{
$this->options['use_upload_name'] = (bool) $flag;
return $this;
}
/**
* @return bool
*/
public function getUseUploadName()
{
return $this->options['use_upload_name'];
}
/**
* @param bool $flag When true, this filter will use the original file
* extension for the target filename
* @return self
*/
public function setUseUploadExtension($flag = true)
{
$this->options['use_upload_extension'] = (bool) $flag;
return $this;
}
/**
* @return bool
*/
public function getUseUploadExtension()
{
return $this->options['use_upload_extension'];
}
/**
* @param bool $flag Shall existing files be overwritten?
* @return self
*/
public function setOverwrite($flag = true)
{
$this->options['overwrite'] = (bool) $flag;
return $this;
}
/**
* @return bool
*/
public function getOverwrite()
{
return $this->options['overwrite'];
}
/**
* @param bool $flag Shall target files have a random postfix attached?
* @return self
*/
public function setRandomize($flag = true)
{
$this->options['randomize'] = (bool) $flag;
return $this;
}
/**
* @return bool
*/
public function getRandomize()
{
return $this->options['randomize'];
}
/**
* Defined by Zend\Filter\Filter
*
* Renames the file $value to the new name set before
* Returns the file $value, removing all but digit characters
*
* @param string|array|UploadedFileInterface $value Full path of file to
* change; $_FILES data array; or UploadedFileInterface instance.
* @return string|array|UploadedFileInterface Returns one of the following:
* - New filename, for string $value
* - Array with tmp_name and name keys for array $value
* - UploadedFileInterface for UploadedFileInterface $value
* @throws Exception\RuntimeException
*/
public function filter($value)
{
// PSR-7 uploaded file
if ($value instanceof UploadedFileInterface) {
return $this->filterPsr7UploadedFile($value);
}
// File upload via traditional SAPI
if (is_array($value) && isset($value['tmp_name'])) {
return $this->filterSapiUploadedFile($value);
}
// String filename
if (is_string($value)) {
return $this->filterStringFilename($value);
}
// Unrecognized; return verbatim
return $value;
}
/**
* @param string $sourceFile Source file path
* @param string $targetFile Target file path
* @throws Exception\RuntimeException
* @return bool
*/
protected function moveUploadedFile($sourceFile, $targetFile)
{
ErrorHandler::start();
$result = move_uploaded_file($sourceFile, $targetFile);
$warningException = ErrorHandler::stop();
if (! $result || null !== $warningException) {
throw new Exception\RuntimeException(
sprintf("File '%s' could not be renamed. An error occurred while processing the file.", $sourceFile),
0,
$warningException
);
}
return $result;
}
/**
* @param string $targetFile Target file path
* @return void
* @throws Exception\InvalidArgumentException
*/
protected function checkFileExists($targetFile)
{
if (! file_exists($targetFile)) {
return;
}
if (! $this->getOverwrite()) {
throw new Exception\InvalidArgumentException(
sprintf("File '%s' could not be renamed. It already exists.", $targetFile)
);
}
unlink($targetFile);
}
/**
* @param $source
* @param $clientFileName
*
* @return string
*/
protected function getFinalTarget($source, $clientFileName)
{
$target = $this->getTarget();
if ($target === null || $target === '*') {
$target = $source;
}
// Get the target directory
if (is_dir($target)) {
$targetDir = $target;
$last = $target[strlen($target) - 1];
if (($last !== '/') && ($last !== '\\')) {
$targetDir .= DIRECTORY_SEPARATOR;
}
} else {
$info = pathinfo($target);
$targetDir = $info['dirname'] . DIRECTORY_SEPARATOR;
}
// Get the target filename
if ($this->getUseUploadName()) {
$targetFile = basename($clientFileName);
} elseif (! is_dir($target)) {
$targetFile = basename($target);
if ($this->getUseUploadExtension() && ! $this->getRandomize()) {
$targetInfo = pathinfo($targetFile);
$sourceinfo = pathinfo($clientFileName);
if (isset($sourceinfo['extension'])) {
$targetFile = $targetInfo['filename'] . '.' . $sourceinfo['extension'];
}
}
} else {
$targetFile = basename($source);
}
if ($this->getRandomize()) {
$targetFile = $this->applyRandomToFilename($clientFileName, $targetFile);
}
return $targetDir . $targetFile;
}
/**
* @param string $source
* @param string $filename
* @return string
*/
protected function applyRandomToFilename($source, $filename)
{
$info = pathinfo($filename);
$filename = $info['filename'] . str_replace('.', '_', uniqid('_', true));
$sourceinfo = pathinfo($source);
$extension = '';
if ($this->getUseUploadExtension() === true && isset($sourceinfo['extension'])) {
$extension .= '.' . $sourceinfo['extension'];
} elseif (isset($info['extension'])) {
$extension .= '.' . $info['extension'];
}
return $filename . $extension;
}
/**
* @param string $fileName
* @return string
*/
private function filterStringFilename($fileName)
{
if (isset($this->alreadyFiltered[$fileName])) {
return $this->alreadyFiltered[$fileName];
}
$targetFile = $this->getFinalTarget($fileName, $fileName);
if ($fileName === $targetFile || ! file_exists($fileName)) {
return $fileName;
}
$this->checkFileExists($targetFile);
$this->moveUploadedFile($fileName, $targetFile);
$this->alreadyFiltered[$fileName] = $targetFile;
return $this->alreadyFiltered[$fileName];
}
/**
* @param array $fileData
* @return array
*/
private function filterSapiUploadedFile(array $fileData)
{
$sourceFile = $fileData['tmp_name'];
if (isset($this->alreadyFiltered[$sourceFile])) {
return $this->alreadyFiltered[$sourceFile];
}
$clientFilename = $fileData['name'];
$targetFile = $this->getFinalTarget($sourceFile, $clientFilename);
if ($sourceFile === $targetFile || ! file_exists($sourceFile)) {
return $fileData;
}
$this->checkFileExists($targetFile);
$this->moveUploadedFile($sourceFile, $targetFile);
$this->alreadyFiltered[$sourceFile] = $fileData;
$this->alreadyFiltered[$sourceFile]['tmp_name'] = $targetFile;
return $this->alreadyFiltered[$sourceFile];
}
/**
* @param UploadedFileInterface $uploadedFile
* @return UploadedFileInterface
* @throws Exception\RuntimeException if no stream factory is composed in the filter.
* @throws Exception\RuntimeException if no uploaded file factory is composed in the filter.
*/
private function filterPsr7UploadedFile(UploadedFileInterface $uploadedFile)
{
$sourceFile = $uploadedFile->getStream()->getMetadata('uri');
if (isset($this->alreadyFiltered[$sourceFile])) {
return $this->alreadyFiltered[$sourceFile];
}
$clientFilename = $uploadedFile->getClientFilename();
$targetFile = $this->getFinalTarget($sourceFile, $clientFilename);
if ($sourceFile === $targetFile || ! file_exists($sourceFile)) {
return $uploadedFile;
}
$this->checkFileExists($targetFile);
$uploadedFile->moveTo($targetFile);
$streamFactory = $this->getStreamFactory();
if (! $streamFactory) {
throw new Exception\RuntimeException(sprintf(
'No PSR-17 %s present; cannot filter file. Please pass the stream_file_factory'
. ' option with a %s instance when creating the filter for use with PSR-7.',
StreamFactoryInterface::class,
StreamFactoryInterface::class
));
}
$stream = $streamFactory->createStreamFromFile($targetFile);
$uploadedFileFactory = $this->getUploadFileFactory();
if (! $uploadedFileFactory) {
throw new Exception\RuntimeException(sprintf(
'No PSR-17 %s present; cannot filter file. Please pass the upload_file_factory'
. ' option with a %s instance when creating the filter for use with PSR-7.',
UploadedFileFactoryInterface::class,
UploadedFileFactoryInterface::class
));
}
$this->alreadyFiltered[$sourceFile] = $uploadedFileFactory->createUploadedFile(
$stream,
filesize($targetFile),
UPLOAD_ERR_OK,
$uploadedFile->getClientFilename(),
$uploadedFile->getClientMediaType()
);
return $this->alreadyFiltered[$sourceFile];
}
}
================================================
FILE: src/Zend/Filter/src/File/UpperCase.php
================================================
filters = new PriorityQueue();
if (null !== $options) {
$this->setOptions($options);
}
}
/**
* @param array|Traversable $options
* @return self
* @throws Exception\InvalidArgumentException
*/
public function setOptions($options)
{
if (! is_array($options) && ! $options instanceof Traversable) {
throw new Exception\InvalidArgumentException(sprintf(
'Expected array or Traversable; received "%s"',
(is_object($options) ? get_class($options) : gettype($options))
));
}
foreach ($options as $key => $value) {
switch (strtolower($key)) {
case 'callbacks':
foreach ($value as $spec) {
$callback = $spec['callback'] ?? false;
$priority = $spec['priority'] ?? static::DEFAULT_PRIORITY;
if ($callback) {
$this->attach($callback, $priority);
}
}
break;
case 'filters':
foreach ($value as $spec) {
$name = $spec['name'] ?? false;
$options = $spec['options'] ?? [];
$priority = $spec['priority'] ?? static::DEFAULT_PRIORITY;
if ($name) {
$this->attachByName($name, $options, $priority);
}
}
break;
default:
// ignore other options
break;
}
}
return $this;
}
/**
* Return the count of attached filters
*
* @return int
*/
#[ReturnTypeWillChange] public function count()
{
return count($this->filters);
}
/**
* Get plugin manager instance
*
* @return FilterPluginManager
*/
public function getPluginManager()
{
if (! $this->plugins) {
$this->setPluginManager(new FilterPluginManager(new ServiceManager()));
}
return $this->plugins;
}
/**
* Set plugin manager instance
*
* @param FilterPluginManager $plugins
* @return self
*/
public function setPluginManager(FilterPluginManager $plugins)
{
$this->plugins = $plugins;
return $this;
}
/**
* Retrieve a filter plugin by name
*
* @param mixed $name
* @param array $options
* @return FilterInterface
*/
public function plugin($name, array $options = [])
{
$plugins = $this->getPluginManager();
return $plugins->get($name, $options);
}
/**
* Attach a filter to the chain
*
* @param callable|FilterInterface $callback A Filter implementation or valid PHP callback
* @param int $priority Priority at which to enqueue filter; defaults to 1000 (higher executes earlier)
* @throws Exception\InvalidArgumentException
* @return self
*/
public function attach($callback, $priority = self::DEFAULT_PRIORITY)
{
if (! is_callable($callback)) {
if (! $callback instanceof FilterInterface) {
throw new Exception\InvalidArgumentException(sprintf(
'Expected a valid PHP callback; received "%s"',
(is_object($callback) ? get_class($callback) : gettype($callback))
));
}
$callback = [$callback, 'filter'];
}
$this->filters->insert($callback, $priority);
return $this;
}
/**
* Attach a filter to the chain using a short name
*
* Retrieves the filter from the attached plugin manager, and then calls attach()
* with the retrieved instance.
*
* @param string $name
* @param mixed $options
* @param int $priority Priority at which to enqueue filter; defaults to 1000 (higher executes earlier)
* @return self
*/
public function attachByName($name, $options = [], $priority = self::DEFAULT_PRIORITY)
{
if (! is_array($options)) {
$options = (array) $options;
} elseif (empty($options)) {
$options = null;
}
$filter = $this->getPluginManager()->get($name, $options);
return $this->attach($filter, $priority);
}
/**
* Merge the filter chain with the one given in parameter
*
* @param FilterChain $filterChain
* @return self
*/
public function merge(FilterChain $filterChain)
{
foreach ($filterChain->filters->toArray(PriorityQueue::EXTR_BOTH) as $item) {
$this->attach($item['data'], $item['priority']);
}
return $this;
}
/**
* Get all the filters
*
* @return PriorityQueue
*/
public function getFilters()
{
return $this->filters;
}
/**
* Returns $value filtered through each filter in the chain
*
* Filters are run in the order in which they were added to the chain (FIFO)
*
* @param mixed $value
* @return mixed
*/
public function filter($value)
{
$chain = clone $this->filters;
$valueFiltered = $value;
foreach ($chain as $filter) {
$valueFiltered = call_user_func($filter, $valueFiltered);
}
return $valueFiltered;
}
/**
* Clone filters
*/
public function __clone()
{
$this->filters = clone $this->filters;
}
/**
* Prepare filter chain for serialization
*
* Plugin manager (property 'plugins') cannot
* be serialized. On wakeup the property remains unset
* and next invocation to getPluginManager() sets
* the default plugin manager instance (FilterPluginManager).
*/
public function __sleep()
{
return ['filters'];
}
}
================================================
FILE: src/Zend/Filter/src/FilterInterface.php
================================================
ToInt::class,
'Int' => ToInt::class,
'null' => ToNull::class,
'Null' => ToNull::class,
// I18n filters
'alnum' => Alnum::class,
'Alnum' => Alnum::class,
'alpha' => Alpha::class,
'Alpha' => Alpha::class,
'numberformat' => NumberFormat::class,
'numberFormat' => NumberFormat::class,
'NumberFormat' => NumberFormat::class,
'numberparse' => NumberParse::class,
'numberParse' => NumberParse::class,
'NumberParse' => NumberParse::class,
// Standard filters
'basename' => BaseName::class,
'Basename' => BaseName::class,
'blacklist' => Blacklist::class,
'Blacklist' => Blacklist::class,
'boolean' => Boolean::class,
'Boolean' => Boolean::class,
'callback' => Callback::class,
'Callback' => Callback::class,
'compress' => Compress::class,
'Compress' => Compress::class,
'dataunitformatter' => DataUnitFormatter::class,
'dataUnitFormatter' => DataUnitFormatter::class,
'DataUnitFormatter' => DataUnitFormatter::class,
'dateselect' => DateSelect::class,
'dateSelect' => DateSelect::class,
'DateSelect' => DateSelect::class,
'datetimeformatter' => DateTimeFormatter::class,
'datetimeFormatter' => DateTimeFormatter::class,
'DatetimeFormatter' => DateTimeFormatter::class,
'dateTimeFormatter' => DateTimeFormatter::class,
'DateTimeFormatter' => DateTimeFormatter::class,
'datetimeselect' => DateTimeSelect::class,
'datetimeSelect' => DateTimeSelect::class,
'DatetimeSelect' => DateTimeSelect::class,
'dateTimeSelect' => DateTimeSelect::class,
'DateTimeSelect' => DateTimeSelect::class,
'decompress' => Decompress::class,
'Decompress' => Decompress::class,
'decrypt' => Decrypt::class,
'Decrypt' => Decrypt::class,
'digits' => Digits::class,
'Digits' => Digits::class,
'dir' => Dir::class,
'Dir' => Dir::class,
'encrypt' => Encrypt::class,
'Encrypt' => Encrypt::class,
'filedecrypt' => File\Decrypt::class,
'fileDecrypt' => File\Decrypt::class,
'FileDecrypt' => File\Decrypt::class,
'fileencrypt' => File\Encrypt::class,
'fileEncrypt' => File\Encrypt::class,
'FileEncrypt' => File\Encrypt::class,
'filelowercase' => File\LowerCase::class,
'fileLowercase' => File\LowerCase::class,
'FileLowercase' => File\LowerCase::class,
'fileLowerCase' => File\LowerCase::class,
'FileLowerCase' => File\LowerCase::class,
'filerename' => File\Rename::class,
'fileRename' => File\Rename::class,
'FileRename' => File\Rename::class,
'filerenameupload' => File\RenameUpload::class,
'fileRenameUpload' => File\RenameUpload::class,
'FileRenameUpload' => File\RenameUpload::class,
'fileuppercase' => File\UpperCase::class,
'fileUppercase' => File\UpperCase::class,
'FileUppercase' => File\UpperCase::class,
'fileUpperCase' => File\UpperCase::class,
'FileUpperCase' => File\UpperCase::class,
'htmlentities' => HtmlEntities::class,
'htmlEntities' => HtmlEntities::class,
'HtmlEntities' => HtmlEntities::class,
'inflector' => Inflector::class,
'Inflector' => Inflector::class,
'monthselect' => MonthSelect::class,
'monthSelect' => MonthSelect::class,
'MonthSelect' => MonthSelect::class,
'pregreplace' => PregReplace::class,
'pregReplace' => PregReplace::class,
'PregReplace' => PregReplace::class,
'realpath' => RealPath::class,
'realPath' => RealPath::class,
'RealPath' => RealPath::class,
'stringprefix' => StringPrefix::class,
'stringPrefix' => StringPrefix::class,
'StringPrefix' => StringPrefix::class,
'stringsuffix' => StringSuffix::class,
'stringSuffix' => StringSuffix::class,
'StringSuffix' => StringSuffix::class,
'stringtolower' => StringToLower::class,
'stringToLower' => StringToLower::class,
'StringToLower' => StringToLower::class,
'stringtoupper' => StringToUpper::class,
'stringToUpper' => StringToUpper::class,
'StringToUpper' => StringToUpper::class,
'stringtrim' => StringTrim::class,
'stringTrim' => StringTrim::class,
'StringTrim' => StringTrim::class,
'stripnewlines' => StripNewlines::class,
'stripNewlines' => StripNewlines::class,
'StripNewlines' => StripNewlines::class,
'striptags' => StripTags::class,
'stripTags' => StripTags::class,
'StripTags' => StripTags::class,
'toint' => ToInt::class,
'toInt' => ToInt::class,
'ToInt' => ToInt::class,
'tofloat' => ToFloat::class,
'toFloat' => ToFloat::class,
'ToFloat' => ToFloat::class,
'tonull' => ToNull::class,
'toNull' => ToNull::class,
'ToNull' => ToNull::class,
'uppercasewords' => UpperCaseWords::class,
'upperCaseWords' => UpperCaseWords::class,
'UpperCaseWords' => UpperCaseWords::class,
'urinormalize' => UriNormalize::class,
'uriNormalize' => UriNormalize::class,
'UriNormalize' => UriNormalize::class,
'whitelist' => Whitelist::class,
'Whitelist' => Whitelist::class,
'wordcamelcasetodash' => Word\CamelCaseToDash::class,
'wordCamelCaseToDash' => Word\CamelCaseToDash::class,
'WordCamelCaseToDash' => Word\CamelCaseToDash::class,
'wordcamelcasetoseparator' => Word\CamelCaseToSeparator::class,
'wordCamelCaseToSeparator' => Word\CamelCaseToSeparator::class,
'WordCamelCaseToSeparator' => Word\CamelCaseToSeparator::class,
'wordcamelcasetounderscore' => Word\CamelCaseToUnderscore::class,
'wordCamelCaseToUnderscore' => Word\CamelCaseToUnderscore::class,
'WordCamelCaseToUnderscore' => Word\CamelCaseToUnderscore::class,
'worddashtocamelcase' => Word\DashToCamelCase::class,
'wordDashToCamelCase' => Word\DashToCamelCase::class,
'WordDashToCamelCase' => Word\DashToCamelCase::class,
'worddashtoseparator' => Word\DashToSeparator::class,
'wordDashToSeparator' => Word\DashToSeparator::class,
'WordDashToSeparator' => Word\DashToSeparator::class,
'worddashtounderscore' => Word\DashToUnderscore::class,
'wordDashToUnderscore' => Word\DashToUnderscore::class,
'WordDashToUnderscore' => Word\DashToUnderscore::class,
'wordseparatortocamelcase' => Word\SeparatorToCamelCase::class,
'wordSeparatorToCamelCase' => Word\SeparatorToCamelCase::class,
'WordSeparatorToCamelCase' => Word\SeparatorToCamelCase::class,
'wordseparatortodash' => Word\SeparatorToDash::class,
'wordSeparatorToDash' => Word\SeparatorToDash::class,
'WordSeparatorToDash' => Word\SeparatorToDash::class,
'wordseparatortoseparator' => Word\SeparatorToSeparator::class,
'wordSeparatorToSeparator' => Word\SeparatorToSeparator::class,
'WordSeparatorToSeparator' => Word\SeparatorToSeparator::class,
'wordunderscoretocamelcase' => Word\UnderscoreToCamelCase::class,
'wordUnderscoreToCamelCase' => Word\UnderscoreToCamelCase::class,
'WordUnderscoreToCamelCase' => Word\UnderscoreToCamelCase::class,
'wordunderscoretostudlycase' => Word\UnderscoreToStudlyCase::class,
'wordUnderscoreToStudlyCase' => Word\UnderscoreToStudlyCase::class,
'WordUnderscoreToStudlyCase' => Word\UnderscoreToStudlyCase::class,
'wordunderscoretodash' => Word\UnderscoreToDash::class,
'wordUnderscoreToDash' => Word\UnderscoreToDash::class,
'WordUnderscoreToDash' => Word\UnderscoreToDash::class,
'wordunderscoretoseparator' => Word\UnderscoreToSeparator::class,
'wordUnderscoreToSeparator' => Word\UnderscoreToSeparator::class,
'WordUnderscoreToSeparator' => Word\UnderscoreToSeparator::class,
];
/**
* Default set of plugins factories
*
* @var array
*/
protected $factories = [
// I18n filters
Alnum::class => InvokableFactory::class,
Alpha::class => InvokableFactory::class,
NumberFormat::class => InvokableFactory::class,
NumberParse::class => InvokableFactory::class,
// Standard filters
BaseName::class => InvokableFactory::class,
Blacklist::class => InvokableFactory::class,
Boolean::class => InvokableFactory::class,
Callback::class => InvokableFactory::class,
Compress::class => InvokableFactory::class,
DataUnitFormatter::class => InvokableFactory::class,
DateSelect::class => InvokableFactory::class,
DateTimeFormatter::class => InvokableFactory::class,
DateTimeSelect::class => InvokableFactory::class,
Decompress::class => InvokableFactory::class,
Decrypt::class => InvokableFactory::class,
Digits::class => InvokableFactory::class,
Dir::class => InvokableFactory::class,
Encrypt::class => InvokableFactory::class,
File\Decrypt::class => InvokableFactory::class,
File\Encrypt::class => InvokableFactory::class,
File\LowerCase::class => InvokableFactory::class,
File\Rename::class => InvokableFactory::class,
File\RenameUpload::class => InvokableFactory::class,
File\UpperCase::class => InvokableFactory::class,
HtmlEntities::class => InvokableFactory::class,
Inflector::class => InvokableFactory::class,
MonthSelect::class => InvokableFactory::class,
PregReplace::class => InvokableFactory::class,
RealPath::class => InvokableFactory::class,
StringPrefix::class => InvokableFactory::class,
StringSuffix::class => InvokableFactory::class,
StringToLower::class => InvokableFactory::class,
StringToUpper::class => InvokableFactory::class,
StringTrim::class => InvokableFactory::class,
StripNewlines::class => InvokableFactory::class,
StripTags::class => InvokableFactory::class,
ToFloat::class => InvokableFactory::class,
ToInt::class => InvokableFactory::class,
ToNull::class => InvokableFactory::class,
UpperCaseWords::class => InvokableFactory::class,
UriNormalize::class => InvokableFactory::class,
Whitelist::class => InvokableFactory::class,
Word\CamelCaseToDash::class => InvokableFactory::class,
Word\CamelCaseToSeparator::class => InvokableFactory::class,
Word\CamelCaseToUnderscore::class => InvokableFactory::class,
Word\DashToCamelCase::class => InvokableFactory::class,
Word\DashToSeparator::class => InvokableFactory::class,
Word\DashToUnderscore::class => InvokableFactory::class,
Word\SeparatorToCamelCase::class => InvokableFactory::class,
Word\SeparatorToDash::class => InvokableFactory::class,
Word\SeparatorToSeparator::class => Word\Service\SeparatorToSeparatorFactory::class,
Word\UnderscoreToCamelCase::class => InvokableFactory::class,
Word\UnderscoreToDash::class => InvokableFactory::class,
Word\UnderscoreToSeparator::class => InvokableFactory::class,
Word\UnderscoreToStudlyCase::class => InvokableFactory::class,
// v2 canonical FQCNs
'zendfiltertoint' => InvokableFactory::class,
'zendfiltertofloat' => InvokableFactory::class,
'zendfiltertonull' => InvokableFactory::class,
'zendi18nfilteralnum' => InvokableFactory::class,
'zendi18nfilteralpha' => InvokableFactory::class,
'zendi18nfilternumberformat' => InvokableFactory::class,
'zendi18nfilternumberparse' => InvokableFactory::class,
'zendfilterbasename' => InvokableFactory::class,
'zendfilterblacklist' => InvokableFactory::class,
'zendfilterboolean' => InvokableFactory::class,
'zendfiltercallback' => InvokableFactory::class,
'zendfiltercompress' => InvokableFactory::class,
'zendfilterdataunitformatter' => InvokableFactory::class,
'zendfilterdateselect' => InvokableFactory::class,
'zendfilterdatetimeformatter' => InvokableFactory::class,
'zendfilterdatetimeselect' => InvokableFactory::class,
'zendfilterdecompress' => InvokableFactory::class,
'zendfilterdecrypt' => InvokableFactory::class,
'zendfilterdigits' => InvokableFactory::class,
'zendfilterdir' => InvokableFactory::class,
'zendfilterencrypt' => InvokableFactory::class,
'zendfilterfiledecrypt' => InvokableFactory::class,
'zendfilterfileencrypt' => InvokableFactory::class,
'zendfilterfilelowercase' => InvokableFactory::class,
'zendfilterfilerename' => InvokableFactory::class,
'zendfilterfilerenameupload' => InvokableFactory::class,
'zendfilterfileuppercase' => InvokableFactory::class,
'zendfilterhtmlentities' => InvokableFactory::class,
'zendfilterinflector' => InvokableFactory::class,
'zendfiltermonthselect' => InvokableFactory::class,
'zendfilterpregreplace' => InvokableFactory::class,
'zendfilterrealpath' => InvokableFactory::class,
'zendfilterstringprefix' => InvokableFactory::class,
'zendfilterstringsuffix' => InvokableFactory::class,
'zendfilterstringtolower' => InvokableFactory::class,
'zendfilterstringtoupper' => InvokableFactory::class,
'zendfilterstringtrim' => InvokableFactory::class,
'zendfilterstripnewlines' => InvokableFactory::class,
'zendfilterstriptags' => InvokableFactory::class,
'zendfilteruppercasewords' => InvokableFactory::class,
'zendfilterurinormalize' => InvokableFactory::class,
'zendfilterwhitelist' => InvokableFactory::class,
'zendfilterwordcamelcasetodash' => InvokableFactory::class,
'zendfilterwordcamelcasetoseparator' => InvokableFactory::class,
'zendfilterwordcamelcasetounderscore' => InvokableFactory::class,
'zendfilterworddashtocamelcase' => InvokableFactory::class,
'zendfilterworddashtoseparator' => InvokableFactory::class,
'zendfilterworddashtounderscore' => InvokableFactory::class,
'zendfilterwordseparatortocamelcase' => InvokableFactory::class,
'zendfilterwordseparatortodash' => InvokableFactory::class,
'zendfilterwordseparatortoseparator' => Word\Service\SeparatorToSeparatorFactory::class,
'zendfilterwordunderscoretocamelcase' => InvokableFactory::class,
'zendfilterwordunderscoretostudlycase' => InvokableFactory::class,
'zendfilterwordunderscoretodash' => InvokableFactory::class,
'zendfilterwordunderscoretoseparator' => InvokableFactory::class,
];
protected $instanceOf = FilterInterface::class;
/**
* Whether or not to share by default; default to false (v2)
*
* @var bool
*/
protected $shareByDefault = false;
/**
* Whether or not to share by default; default to false (v3)
*
* @var bool
*/
protected $sharedByDefault = false;
/**
* {@inheritdoc}
*/
public function validate($plugin)
{
if ($plugin instanceof $this->instanceOf) {
// we're okay
return;
}
if (is_callable($plugin)) {
// also okay
return;
}
throw new InvalidServiceException(sprintf(
'Plugin of type %s is invalid; must implement %s\FilterInterface or be callable',
(is_object($plugin) ? get_class($plugin) : gettype($plugin)),
__NAMESPACE__
));
}
/**
* Validate the plugin (v2)
*
* Checks that the filter loaded is either a valid callback or an instance
* of FilterInterface.
*
* @param mixed $plugin
* @return void
* @throws Exception\RuntimeException if invalid
*/
public function validatePlugin($plugin)
{
try {
$this->validate($plugin);
} catch (InvalidServiceException $e) {
throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
}
}
}
================================================
FILE: src/Zend/Filter/src/FilterPluginManagerFactory.php
================================================
has('ServiceListener')) {
return $pluginManager;
}
// If we do not have a config service, nothing more to do
if (! $container->has('config')) {
return $pluginManager;
}
$config = $container->get('config');
// If we do not have filters configuration, nothing more to do
if (! isset($config['filters']) || ! is_array($config['filters'])) {
return $pluginManager;
}
// Wire service configuration for validators
(new Config($config['filters']))->configureServiceManager($pluginManager);
return $pluginManager;
}
/**
* {@inheritDoc}
*
* @return FilterPluginManager
*/
public function createService(ServiceLocatorInterface $container, $name = null, $requestedName = null)
{
return $this($container, $requestedName ?: FilterPluginManager::class, $this->creationOptions);
}
/**
* zend-servicemanager v2 support for invocation options.
*
* @param array $options
* @return void
*/
public function setCreationOptions(array $options)
{
$this->creationOptions = $options;
}
}
================================================
FILE: src/Zend/Filter/src/FilterProviderInterface.php
================================================
setQuoteStyle($options['quotestyle']);
$this->setEncoding($options['encoding']);
$this->setDoubleQuote($options['doublequote']);
}
/**
* Returns the quoteStyle option
*
* @return int
*/
public function getQuoteStyle()
{
return $this->quoteStyle;
}
/**
* Sets the quoteStyle option
*
* @param int $quoteStyle
* @return self Provides a fluent interface
*/
public function setQuoteStyle($quoteStyle)
{
$this->quoteStyle = $quoteStyle;
return $this;
}
/**
* Get encoding
*
* @return string
*/
public function getEncoding()
{
return $this->encoding;
}
/**
* Set encoding
*
* @param string $value
* @return self
*/
public function setEncoding($value)
{
$this->encoding = (string) $value;
return $this;
}
/**
* Returns the charSet option
*
* Proxies to {@link getEncoding()}
*
* @return string
*/
public function getCharSet()
{
return $this->getEncoding();
}
/**
* Sets the charSet option
*
* Proxies to {@link setEncoding()}
*
* @param string $charSet
* @return self Provides a fluent interface
*/
public function setCharSet($charSet)
{
return $this->setEncoding($charSet);
}
/**
* Returns the doubleQuote option
*
* @return bool
*/
public function getDoubleQuote()
{
return $this->doubleQuote;
}
/**
* Sets the doubleQuote option
*
* @param bool $doubleQuote
* @return self Provides a fluent interface
*/
public function setDoubleQuote($doubleQuote)
{
$this->doubleQuote = (bool) $doubleQuote;
return $this;
}
/**
* Defined by Zend\Filter\FilterInterface
*
* Returns the string $value, converting characters to their corresponding HTML entity
* equivalents where they exist
*
* If the value provided is non-scalar, the value will remain unfiltered
*
* @param string $value
* @return string|mixed
* @throws Exception\DomainException on encoding mismatches
*/
public function filter($value)
{
if (! is_scalar($value)) {
return $value;
}
$value = (string) $value;
$filtered = htmlentities($value, $this->getQuoteStyle(), $this->getEncoding(), $this->getDoubleQuote());
if (strlen($value) && ! strlen($filtered)) {
if (! function_exists('iconv')) {
throw new Exception\DomainException('Encoding mismatch has resulted in htmlentities errors');
}
$enc = $this->getEncoding();
$value = iconv('', $this->getEncoding() . '//IGNORE', $value);
$filtered = htmlentities($value, $this->getQuoteStyle(), $enc, $this->getDoubleQuote());
if (! strlen($filtered)) {
throw new Exception\DomainException('Encoding mismatch has resulted in htmlentities errors');
}
}
return $filtered;
}
}
================================================
FILE: src/Zend/Filter/src/Inflector.php
================================================
setOptions($options);
}
/**
* Retrieve plugin manager
*
* @return FilterPluginManager
*/
public function getPluginManager()
{
if (! $this->pluginManager instanceof FilterPluginManager) {
$this->setPluginManager(new FilterPluginManager(new ServiceManager()));
}
return $this->pluginManager;
}
/**
* Set plugin manager
*
* @param FilterPluginManager $manager
* @return self
*/
public function setPluginManager(FilterPluginManager $manager)
{
$this->pluginManager = $manager;
return $this;
}
/**
* Set options
*
* @param array|Traversable $options
* @return self
*/
public function setOptions($options)
{
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
}
// Set plugin manager
if (array_key_exists('pluginManager', $options)) {
if (is_scalar($options['pluginManager']) && class_exists($options['pluginManager'])) {
$options['pluginManager'] = new $options['pluginManager'];
}
$this->setPluginManager($options['pluginManager']);
}
if (array_key_exists('throwTargetExceptionsOn', $options)) {
$this->setThrowTargetExceptionsOn($options['throwTargetExceptionsOn']);
}
if (array_key_exists('targetReplacementIdentifier', $options)) {
$this->setTargetReplacementIdentifier($options['targetReplacementIdentifier']);
}
if (array_key_exists('target', $options)) {
$this->setTarget($options['target']);
}
if (array_key_exists('rules', $options)) {
$this->addRules($options['rules']);
}
return $this;
}
/**
* Set Whether or not the inflector should throw an exception when a replacement
* identifier is still found within an inflected target.
*
* @param bool $throwTargetExceptionsOn
* @return self
*/
public function setThrowTargetExceptionsOn($throwTargetExceptionsOn)
{
$this->throwTargetExceptionsOn = (bool) $throwTargetExceptionsOn;
return $this;
}
/**
* Will exceptions be thrown?
*
* @return bool
*/
public function isThrowTargetExceptionsOn()
{
return $this->throwTargetExceptionsOn;
}
/**
* Set the Target Replacement Identifier, by default ':'
*
* @param string $targetReplacementIdentifier
* @return self
*/
public function setTargetReplacementIdentifier($targetReplacementIdentifier)
{
if ($targetReplacementIdentifier) {
$this->targetReplacementIdentifier = (string) $targetReplacementIdentifier;
}
return $this;
}
/**
* Get Target Replacement Identifier
*
* @return string
*/
public function getTargetReplacementIdentifier()
{
return $this->targetReplacementIdentifier;
}
/**
* Set a Target
* ex: 'scripts/:controller/:action.:suffix'
*
* @param string $target
* @return self
*/
public function setTarget($target)
{
$this->target = (string) $target;
return $this;
}
/**
* Retrieve target
*
* @return string
*/
public function getTarget()
{
return $this->target;
}
/**
* Set Target Reference
*
* @param string $target
* @return self
*/
public function setTargetReference(&$target)
{
$this->target =& $target;
return $this;
}
/**
* Is the same as calling addRules() with the exception that it
* clears the rules before adding them.
*
* @param array $rules
* @return self
*/
public function setRules(array $rules)
{
$this->clearRules();
$this->addRules($rules);
return $this;
}
/**
* Multi-call to setting filter rules.
*
* If prefixed with a ":" (colon), a filter rule will be added. If not
* prefixed, a static replacement will be added.
*
* ex:
* array(
* ':controller' => array('CamelCaseToUnderscore', 'StringToLower'),
* ':action' => array('CamelCaseToUnderscore', 'StringToLower'),
* 'suffix' => 'phtml'
* );
*
* @param array $rules
* @return self
*/
public function addRules(array $rules)
{
$keys = array_keys($rules);
foreach ($keys as $spec) {
if ($spec[0] === ':') {
$this->addFilterRule($spec, $rules[$spec]);
} else {
$this->setStaticRule($spec, $rules[$spec]);
}
}
return $this;
}
/**
* Get rules
*
* By default, returns all rules. If a $spec is provided, will return those
* rules if found, false otherwise.
*
* @param string $spec
* @return array|false
*/
public function getRules($spec = null)
{
if (null !== $spec) {
$spec = $this->_normalizeSpec($spec);
if (isset($this->rules[$spec])) {
return $this->rules[$spec];
}
return false;
}
return $this->rules;
}
/**
* Returns a rule set by setFilterRule(), a numeric index must be provided
*
* @param string $spec
* @param int $index
* @return FilterInterface|false
*/
public function getRule($spec, $index)
{
$spec = $this->_normalizeSpec($spec);
if (isset($this->rules[$spec]) && is_array($this->rules[$spec])) {
if (isset($this->rules[$spec][$index])) {
return $this->rules[$spec][$index];
}
}
return false;
}
/**
* Clears the rules currently in the inflector
*
* @return self
*/
public function clearRules()
{
$this->rules = [];
return $this;
}
/**
* Set a filtering rule for a spec. $ruleSet can be a string, Filter object
* or an array of strings or filter objects.
*
* @param string $spec
* @param array|string|\Zend\Filter\FilterInterface $ruleSet
* @return self
*/
public function setFilterRule($spec, $ruleSet)
{
$spec = $this->_normalizeSpec($spec);
$this->rules[$spec] = [];
return $this->addFilterRule($spec, $ruleSet);
}
/**
* Add a filter rule for a spec
*
* @param mixed $spec
* @param mixed $ruleSet
* @return self
*/
public function addFilterRule($spec, $ruleSet)
{
$spec = $this->_normalizeSpec($spec);
if (! isset($this->rules[$spec])) {
$this->rules[$spec] = [];
}
if (! is_array($ruleSet)) {
$ruleSet = [$ruleSet];
}
if (is_string($this->rules[$spec])) {
$temp = $this->rules[$spec];
$this->rules[$spec] = [];
$this->rules[$spec][] = $temp;
}
foreach ($ruleSet as $rule) {
$this->rules[$spec][] = $this->_getRule($rule);
}
return $this;
}
/**
* Set a static rule for a spec. This is a single string value
*
* @param string $name
* @param string $value
* @return self
*/
public function setStaticRule($name, $value)
{
$name = $this->_normalizeSpec($name);
$this->rules[$name] = (string) $value;
return $this;
}
/**
* Set Static Rule Reference.
*
* This allows a consuming class to pass a property or variable
* in to be referenced when its time to build the output string from the
* target.
*
* @param string $name
* @param mixed $reference
* @return self
*/
public function setStaticRuleReference($name, &$reference)
{
$name = $this->_normalizeSpec($name);
$this->rules[$name] =& $reference;
return $this;
}
/**
* Inflect
*
* @param string|array $source
* @throws Exception\RuntimeException
* @return string
*/
public function filter($source)
{
// clean source
foreach ((array) $source as $sourceName => $sourceValue) {
$source[ltrim($sourceName, ':')] = $sourceValue;
}
$pregQuotedTargetReplacementIdentifier = preg_quote($this->targetReplacementIdentifier, '#');
$processedParts = [];
foreach ($this->rules as $ruleName => $ruleValue) {
if (isset($source[$ruleName])) {
if (is_string($ruleValue)) {
// overriding the set rule
$processedParts['#' . $pregQuotedTargetReplacementIdentifier . $ruleName . '#'] = str_replace(
'\\',
'\\\\',
$source[$ruleName]
);
} elseif (is_array($ruleValue)) {
$processedPart = $source[$ruleName];
foreach ($ruleValue as $ruleFilter) {
$processedPart = $ruleFilter($processedPart);
}
$processedParts['#' . $pregQuotedTargetReplacementIdentifier . $ruleName . '#'] = str_replace(
'\\',
'\\\\',
$processedPart
);
}
} elseif (is_string($ruleValue)) {
$processedParts['#' . $pregQuotedTargetReplacementIdentifier . $ruleName . '#'] = str_replace(
'\\',
'\\\\',
$ruleValue
);
}
}
// all of the values of processedParts would have been str_replace('\\', '\\\\', ..)'d
// to disable preg_replace backreferences
$inflectedTarget = preg_replace(array_keys($processedParts), array_values($processedParts), $this->target);
if ($this->throwTargetExceptionsOn
&& preg_match('#(?=' . $pregQuotedTargetReplacementIdentifier.'[A-Za-z]{1})#', $inflectedTarget)
) {
throw new Exception\RuntimeException(
'A replacement identifier ' . $this->targetReplacementIdentifier
. ' was found inside the inflected target, perhaps a rule was not satisfied with a target source? '
. 'Unsatisfied inflected target: ' . $inflectedTarget
);
}
return $inflectedTarget;
}
/**
* Normalize spec string
*
* @param string $spec
* @return string
*/
// @codingStandardsIgnoreStart
protected function _normalizeSpec($spec)
{
// @codingStandardsIgnoreEnd
return ltrim((string) $spec, ':&');
}
/**
* Resolve named filters and convert them to filter objects.
*
* @param string $rule
* @return FilterInterface
*/
// @codingStandardsIgnoreStart
protected function _getRule($rule)
{
// @codingStandardsIgnoreEnd
if ($rule instanceof FilterInterface) {
return $rule;
}
$rule = (string) $rule;
return $this->getPluginManager()->get($rule);
}
}
================================================
FILE: src/Zend/Filter/src/Module.php
================================================
$provider->getDependencyConfig(),
];
}
/**
* Register a specification for the FilterManager with the ServiceListener.
*
* @param \Zend\ModuleManager\ModuleManager $moduleManager
* @return void
*/
public function init($moduleManager)
{
$event = $moduleManager->getEvent();
$container = $event->getParam('ServiceManager');
$serviceListener = $container->get('ServiceListener');
$serviceListener->addServiceManager(
'FilterManager',
'filters',
FilterProviderInterface::class,
'getFilterConfig'
);
}
}
================================================
FILE: src/Zend/Filter/src/MonthSelect.php
================================================
null,
'replacement' => '',
];
/**
* Constructor
* Supported options are
* 'pattern' => matching pattern
* 'replacement' => replace with this
*
* @param array|Traversable|string|null $options
*/
public function __construct($options = null)
{
if ($options instanceof Traversable) {
$options = iterator_to_array($options);
}
if (! is_array($options) || (! isset($options['pattern']) && ! isset($options['replacement']))) {
$args = func_get_args();
if (isset($args[0])) {
$this->setPattern($args[0]);
}
if (isset($args[1])) {
$this->setReplacement($args[1]);
}
} else {
$this->setOptions($options);
}
}
/**
* Set the regex pattern to search for
* @see preg_replace()
*
* @param string|array $pattern - same as the first argument of preg_replace
* @return self
* @throws Exception\InvalidArgumentException
*/
public function setPattern($pattern)
{
if (! is_array($pattern) && ! is_string($pattern)) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects pattern to be array or string; received "%s"',
__METHOD__,
(is_object($pattern) ? get_class($pattern) : gettype($pattern))
));
}
if (is_array($pattern)) {
foreach ($pattern as $p) {
$this->validatePattern($p);
}
}
if (is_string($pattern)) {
$this->validatePattern($pattern);
}
$this->options['pattern'] = $pattern;
return $this;
}
/**
* Get currently set match pattern
*
* @return string|array
*/
public function getPattern()
{
return $this->options['pattern'];
}
/**
* Set the replacement array/string
* @see preg_replace()
*
* @param array|string $replacement - same as the second argument of preg_replace
* @return self
* @throws Exception\InvalidArgumentException
*/
public function setReplacement($replacement)
{
if (! is_array($replacement) && ! is_string($replacement)) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects replacement to be array or string; received "%s"',
__METHOD__,
(is_object($replacement) ? get_class($replacement) : gettype($replacement))
));
}
$this->options['replacement'] = $replacement;
return $this;
}
/**
* Get currently set replacement value
*
* @return string|array
*/
public function getReplacement()
{
return $this->options['replacement'];
}
/**
* Perform regexp replacement as filter
*
* @param mixed $value
* @return mixed
* @throws Exception\RuntimeException
*/
public function filter($value)
{
if (! is_scalar($value) && ! is_array($value)) {
return $value;
}
if ($this->options['pattern'] === null) {
throw new Exception\RuntimeException(sprintf(
'Filter %s does not have a valid pattern set',
get_class($this)
));
}
return preg_replace($this->options['pattern'], $this->options['replacement'], $value);
}
/**
* Validate a pattern and ensure it does not contain the "e" modifier
*
* @param string $pattern
* @return bool
* @throws Exception\InvalidArgumentException
*/
protected function validatePattern($pattern)
{
if (! preg_match('/(?[imsxeADSUXJu]+)$/', $pattern, $matches)) {
return true;
}
if (str_contains($matches['modifier'], 'e')) {
throw new Exception\InvalidArgumentException(sprintf(
'Pattern for a PregReplace filter may not contain the "e" pattern modifier; received "%s"',
$pattern
));
}
}
}
================================================
FILE: src/Zend/Filter/src/RealPath.php
================================================
true
];
/**
* Class constructor
*
* @param bool|Traversable $existsOrOptions Options to set
*/
public function __construct($existsOrOptions = true)
{
if ($existsOrOptions !== null) {
if (! static::isOptions($existsOrOptions)) {
$this->setExists($existsOrOptions);
} else {
$this->setOptions($existsOrOptions);
}
}
}
/**
* Sets if the path has to exist
* TRUE when the path must exist
* FALSE when not existing paths can be given
*
* @param bool $flag Path must exist
* @return self
*/
public function setExists($flag = true)
{
$this->options['exists'] = (bool) $flag;
return $this;
}
/**
* Returns true if the filtered path must exist
*
* @return bool
*/
public function getExists()
{
return $this->options['exists'];
}
/**
* Defined by Zend\Filter\FilterInterface
*
* Returns realpath($value)
*
* If the value provided is non-scalar, the value will remain unfiltered
*
* @param string $value
* @return string|mixed
*/
public function filter($value)
{
if (! is_string($value)) {
return $value;
}
$path = (string) $value;
if ($this->options['exists']) {
return realpath($path);
}
ErrorHandler::start();
$realpath = realpath($path);
ErrorHandler::stop();
if ($realpath) {
return $realpath;
}
$drive = '';
if (stripos(PHP_OS, 'WIN') === 0) {
$path = preg_replace('/[\\\\\/]/', DIRECTORY_SEPARATOR, $path);
if (preg_match('/([a-zA-Z]\:)(.*)/', $path, $matches)) {
[, $drive, $path] = $matches;
} else {
$cwd = getcwd();
$drive = substr($cwd, 0, 2);
if (!str_starts_with($path, DIRECTORY_SEPARATOR)) {
$path = substr($cwd, 3) . DIRECTORY_SEPARATOR . $path;
}
}
} elseif (!str_starts_with($path, DIRECTORY_SEPARATOR)) {
$path = getcwd() . DIRECTORY_SEPARATOR . $path;
}
$stack = [];
$parts = explode(DIRECTORY_SEPARATOR, $path);
foreach ($parts as $dir) {
if ($dir !== '' && $dir !== '.') {
if ($dir === '..') {
array_pop($stack);
} else {
$stack[] = $dir;
}
}
}
return $drive . DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $stack);
}
}
================================================
FILE: src/Zend/Filter/src/StaticFilter.php
================================================
get($classBaseName, $args);
return $filter->filter($value);
}
}
================================================
FILE: src/Zend/Filter/src/StringPrefix.php
================================================
*/
protected $options = [
'prefix' => null,
];
/**
* @param string|array|Traversable $options
*/
public function __construct($options = null)
{
if ($options !== null) {
$this->setOptions($options);
}
}
/**
* Set the prefix string
*
* @param string $prefix
* @return self
* @throws Exception\InvalidArgumentException
*/
public function setPrefix($prefix)
{
if (! is_string($prefix)) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects "prefix" to be string; received "%s"',
__METHOD__,
is_object($prefix) ? get_class($prefix) : gettype($prefix)
));
}
$this->options['prefix'] = $prefix;
return $this;
}
/**
* Returns the prefix string, which is appended at the beginning of the input value
*
* @return string
*/
public function getPrefix()
{
if (! isset($this->options['prefix'])) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects a "prefix" option; none given',
__CLASS__
));
}
return $this->options['prefix'];
}
/**
* {@inheritdoc}
*/
public function filter($value)
{
if (! is_scalar($value)) {
return $value;
}
$value = (string) $value;
return $this->getPrefix() . $value;
}
}
================================================
FILE: src/Zend/Filter/src/StringSuffix.php
================================================
*/
protected $options = [
'suffix' => null,
];
/**
* @param string|array|Traversable $options
*/
public function __construct($options = null)
{
if ($options !== null) {
$this->setOptions($options);
}
}
/**
* Set the suffix string
*
* @param string $suffix
*
* @return self
* @throws Exception\InvalidArgumentException
*/
public function setSuffix($suffix)
{
if (! is_string($suffix)) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects "suffix" to be string; received "%s"',
__METHOD__,
is_object($suffix) ? get_class($suffix) : gettype($suffix)
));
}
$this->options['suffix'] = $suffix;
return $this;
}
/**
* Returns the suffix string, which is appended at the end of the input value
*
* @return string
* @throws Exception\InvalidArgumentException
*/
public function getSuffix()
{
if (! isset($this->options['suffix'])) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects a "suffix" option; none given',
__CLASS__
));
}
return $this->options['suffix'];
}
/**
* {@inheritdoc}
*/
public function filter($value)
{
if (! is_scalar($value)) {
return $value;
}
$value = (string) $value;
return $value . $this->getSuffix();
}
}
================================================
FILE: src/Zend/Filter/src/StringToLower.php
================================================
null,
];
/**
* Constructor
*
* @param string|array|Traversable $encodingOrOptions OPTIONAL
*/
public function __construct($encodingOrOptions = null)
{
if ($encodingOrOptions !== null) {
if (! static::isOptions($encodingOrOptions)) {
$this->setEncoding($encodingOrOptions);
} else {
$this->setOptions($encodingOrOptions);
}
}
}
/**
* Defined by Zend\Filter\FilterInterface
*
* Returns the string $value, converting characters to lowercase as necessary
*
* If the value provided is non-scalar, the value will remain unfiltered
*
* @param string $value
* @return string|mixed
*/
public function filter($value)
{
if (! is_scalar($value)) {
return $value;
}
$value = (string) $value;
if (null !== $this->getEncoding()) {
return mb_strtolower($value, $this->options['encoding']);
}
return strtolower($value);
}
}
================================================
FILE: src/Zend/Filter/src/StringToUpper.php
================================================
null,
];
/**
* Constructor
*
* @param string|array|Traversable $encodingOrOptions OPTIONAL
*/
public function __construct($encodingOrOptions = null)
{
if ($encodingOrOptions !== null) {
if (! static::isOptions($encodingOrOptions)) {
$this->setEncoding($encodingOrOptions);
} else {
$this->setOptions($encodingOrOptions);
}
}
}
/**
* Defined by Zend\Filter\FilterInterface
*
* Returns the string $value, converting characters to uppercase as necessary
*
* If the value provided is non-scalar, the value will remain unfiltered
*
* @param string $value
* @return string|mixed
*/
public function filter($value)
{
if (! is_scalar($value)) {
return $value;
}
$value = (string) $value;
if (null !== $this->getEncoding()) {
return mb_strtoupper($value, $this->options['encoding']);
}
return strtoupper($value);
}
}
================================================
FILE: src/Zend/Filter/src/StringTrim.php
================================================
null,
];
/**
* Sets filter options
*
* @param string|array|Traversable $charlistOrOptions
*/
public function __construct($charlistOrOptions = null)
{
if ($charlistOrOptions !== null) {
if (! is_array($charlistOrOptions) && ! $charlistOrOptions instanceof Traversable) {
$this->setCharList($charlistOrOptions);
} else {
$this->setOptions($charlistOrOptions);
}
}
}
/**
* Sets the charList option
*
* @param string $charList
* @return self Provides a fluent interface
*/
public function setCharList($charList)
{
if (! strlen($charList)) {
$charList = null;
}
$this->options['charlist'] = $charList;
return $this;
}
/**
* Returns the charList option
*
* @return string|null
*/
public function getCharList()
{
return $this->options['charlist'];
}
/**
* Defined by Zend\Filter\FilterInterface
*
* Returns the string $value with characters stripped from the beginning and end
*
* @param string $value
* @return string
*/
public function filter($value)
{
if (! is_string($value)) {
return $value;
}
$value = (string) $value;
if (null === $this->options['charlist']) {
return $this->unicodeTrim($value);
}
return $this->unicodeTrim($value, $this->options['charlist']);
}
/**
* Unicode aware trim method
* Fixes a PHP problem
*
* @param string $value
* @param string $charlist
* @return string
*/
protected function unicodeTrim($value, $charlist = '\\\\s')
{
$chars = preg_replace(
['/[\^\-\]\\\]/S', '/\\\{4}/S', '/\//'],
['\\\\\\0', '\\', '\/'],
$charlist
);
$pattern = '/^[' . $chars . ']+|[' . $chars . ']+$/usSD';
return preg_replace($pattern, '', $value);
}
}
================================================
FILE: src/Zend/Filter/src/StripNewlines.php
================================================
Tags which are allowed
* 'allowAttribs' => Attributes which are allowed
* 'allowComments' => Are comments allowed ?
*
* @param string|array|Traversable $options
*/
public function __construct($options = null)
{
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
}
if ((! is_array($options)) || (is_array($options) && ! array_key_exists('allowTags', $options) &&
! array_key_exists('allowAttribs', $options) && ! array_key_exists('allowComments', $options))) {
$options = func_get_args();
$temp['allowTags'] = array_shift($options);
if (! empty($options)) {
$temp['allowAttribs'] = array_shift($options);
}
if (! empty($options)) {
$temp['allowComments'] = array_shift($options);
}
$options = $temp;
}
if (array_key_exists('allowTags', $options)) {
$this->setTagsAllowed($options['allowTags']);
}
if (array_key_exists('allowAttribs', $options)) {
$this->setAttributesAllowed($options['allowAttribs']);
}
}
/**
* Returns the tagsAllowed option
*
* @return array
*/
public function getTagsAllowed()
{
return $this->tagsAllowed;
}
/**
* Sets the tagsAllowed option
*
* @param array|string $tagsAllowed
* @return self Provides a fluent interface
*/
public function setTagsAllowed($tagsAllowed)
{
if (! is_array($tagsAllowed)) {
$tagsAllowed = [$tagsAllowed];
}
foreach ($tagsAllowed as $index => $element) {
// If the tag was provided without attributes
if (is_int($index) && is_string($element)) {
// Canonicalize the tag name
$tagName = strtolower($element);
// Store the tag as allowed with no attributes
$this->tagsAllowed[$tagName] = [];
} elseif (is_string($index) && (is_array($element) || is_string($element))) {
// Otherwise, if a tag was provided with attributes
// Canonicalize the tag name
$tagName = strtolower($index);
// Canonicalize the attributes
if (is_string($element)) {
$element = [$element];
}
// Store the tag as allowed with the provided attributes
$this->tagsAllowed[$tagName] = [];
foreach ($element as $attribute) {
if (is_string($attribute)) {
// Canonicalize the attribute name
$attributeName = strtolower($attribute);
$this->tagsAllowed[$tagName][$attributeName] = null;
}
}
}
}
return $this;
}
/**
* Returns the attributesAllowed option
*
* @return array
*/
public function getAttributesAllowed()
{
return $this->attributesAllowed;
}
/**
* Sets the attributesAllowed option
*
* @param array|string $attributesAllowed
* @return self Provides a fluent interface
*/
public function setAttributesAllowed($attributesAllowed)
{
if (! is_array($attributesAllowed)) {
$attributesAllowed = [$attributesAllowed];
}
// Store each attribute as allowed
foreach ($attributesAllowed as $attribute) {
if (is_string($attribute)) {
// Canonicalize the attribute name
$attributeName = strtolower($attribute);
$this->attributesAllowed[$attributeName] = null;
}
}
return $this;
}
/**
* Defined by Zend\Filter\FilterInterface
*
* If the value provided is non-scalar, the value will remain unfiltered
*
* @todo improve docblock descriptions
* @param string $value
* @return string|mixed
*/
public function filter($value)
{
if (! is_scalar($value)) {
return $value;
}
$value = (string) $value;
// Strip HTML comments first
$open = '';
$closeLen = strlen($close);
while (($start = strpos($value, $open)) !== false) {
$end = strpos($value, $close, $start + $openLen);
if ($end === false) {
$value = substr($value, 0, $start);
} else {
$value = substr($value, 0, $start) . substr($value, $end + $closeLen);
}
}
// Initialize accumulator for filtered data
$dataFiltered = '';
// Parse the input data iteratively as regular pre-tag text followed by a
// tag; either may be empty strings
preg_match_all('/([^<]*)([^>]*>?)/', (string) $value, $matches);
// Iterate over each set of matches
foreach ($matches[1] as $index => $preTag) {
// If the pre-tag text is non-empty, strip any ">" characters from it
if (strlen($preTag)) {
$preTag = str_replace('>', '', $preTag);
}
// If a tag exists in this match, then filter the tag
$tag = $matches[2][$index];
if (strlen($tag)) {
$tagFiltered = $this->_filterTag($tag);
} else {
$tagFiltered = '';
}
// Add the filtered pre-tag text and filtered tag to the data buffer
$dataFiltered .= $preTag . $tagFiltered;
}
// Return the filtered data
return $dataFiltered;
}
/**
* Filters a single tag against the current option settings
*
* @param string $tag
* @return string
*/
// @codingStandardsIgnoreStart
protected function _filterTag($tag)
{
// @codingStandardsIgnoreEnd
// Parse the tag into:
// 1. a starting delimiter (mandatory)
// 2. a tag name (if available)
// 3. a string of attributes (if available)
// 4. an ending delimiter (if available)
$isMatch = preg_match('~(?)(\w*)((/(?!>)|[^/>])*)(/?>)~', $tag, $matches);
// If the tag does not match, then strip the tag entirely
if (! $isMatch) {
return '';
}
// Save the matches to more meaningfully named variables
$tagStart = $matches[1];
$tagName = strtolower($matches[2]);
$tagAttributes = $matches[3];
$tagEnd = $matches[5];
// If the tag is not an allowed tag, then remove the tag entirely
if (! isset($this->tagsAllowed[$tagName])) {
return '';
}
// Trim the attribute string of whitespace at the ends
$tagAttributes = trim($tagAttributes);
// If there are non-whitespace characters in the attribute string
if (strlen($tagAttributes)) {
// Parse iteratively for well-formed attributes
preg_match_all('/([\w-]+)\s*=\s*(?:(")(.*?)"|(\')(.*?)\')/s', $tagAttributes, $matches);
// Initialize valid attribute accumulator
$tagAttributes = '';
// Iterate over each matched attribute
foreach ($matches[1] as $index => $attributeName) {
$attributeName = strtolower($attributeName);
$attributeDelimiter = empty($matches[2][$index]) ? $matches[4][$index] : $matches[2][$index];
$attributeValue = $matches[3][$index] === '' ? $matches[5][$index] : $matches[3][$index];
// If the attribute is not allowed, then remove it entirely
if (! array_key_exists($attributeName, $this->tagsAllowed[$tagName])
&& ! array_key_exists($attributeName, $this->attributesAllowed)) {
continue;
}
// Add the attribute to the accumulator
$tagAttributes .= " $attributeName=" . $attributeDelimiter
. $attributeValue . $attributeDelimiter;
}
}
// Reconstruct tags ending with "/>" as backwards-compatible XHTML tag
if (str_contains($tagEnd, '/')) {
$tagEnd = " $tagEnd";
}
// Return the filtered tag
return $tagStart . $tagName . $tagAttributes . $tagEnd;
}
}
================================================
FILE: src/Zend/Filter/src/ToFloat.php
================================================
'boolean',
self::TYPE_INTEGER => 'integer',
self::TYPE_EMPTY_ARRAY => 'array',
self::TYPE_STRING => 'string',
self::TYPE_ZERO_STRING => 'zero',
self::TYPE_FLOAT => 'float',
self::TYPE_ALL => 'all',
];
/**
* @var array
*/
protected $options = [
'type' => self::TYPE_ALL,
];
/**
* Constructor
*
* @param int|string|array|Traversable|null $typeOrOptions
*/
public function __construct($typeOrOptions = null)
{
if ($typeOrOptions !== null) {
if ($typeOrOptions instanceof Traversable) {
$typeOrOptions = iterator_to_array($typeOrOptions);
}
if (is_array($typeOrOptions)) {
if (isset($typeOrOptions['type'])) {
$this->setOptions($typeOrOptions);
} else {
$this->setType($typeOrOptions);
}
} else {
$this->setType($typeOrOptions);
}
}
}
/**
* Set boolean types
*
* @param int|string|array $type
* @throws Exception\InvalidArgumentException
* @return self
*/
public function setType($type = null)
{
if (is_array($type)) {
$detected = 0;
foreach ($type as $value) {
if (is_int($value)) {
$detected |= $value;
} elseif (($found = array_search($value, $this->constants, true)) !== false) {
$detected |= $found;
}
}
$type = $detected;
} elseif (is_string($type) && ($found = array_search($type, $this->constants, true)) !== false) {
$type = $found;
}
if (! is_int($type) || ($type < 0) || ($type > self::TYPE_ALL)) {
throw new Exception\InvalidArgumentException(sprintf(
'Unknown type value "%s" (%s)',
$type,
gettype($type)
));
}
$this->options['type'] = $type;
return $this;
}
/**
* Returns defined boolean types
*
* @return int
*/
public function getType()
{
return $this->options['type'];
}
/**
* Defined by Zend\Filter\FilterInterface
*
* Returns null representation of $value, if value is empty and matches
* types that should be considered null.
*
* @param null|array|bool|float|int|string $value
* @return null|mixed
*/
public function filter($value)
{
$type = $this->getType();
// FLOAT (0.0)
if ($type & self::TYPE_FLOAT) {
if (is_float($value) && $value === 0.0) {
return null;
}
}
// STRING ZERO ('0')
if ($type & self::TYPE_ZERO_STRING) {
if (is_string($value) && $value === '0') {
return null;
}
}
// STRING ('')
if ($type & self::TYPE_STRING) {
if (is_string($value) && $value === '') {
return null;
}
}
// EMPTY_ARRAY (array())
if ($type & self::TYPE_EMPTY_ARRAY) {
if (is_array($value) && $value === []) {
return null;
}
}
// INTEGER (0)
if ($type & self::TYPE_INTEGER) {
if (is_int($value) && $value === 0) {
return null;
}
}
// BOOLEAN (false)
if ($type & self::TYPE_BOOLEAN) {
if (is_bool($value) && $value === false) {
return null;
}
}
return $value;
}
}
================================================
FILE: src/Zend/Filter/src/UpperCaseWords.php
================================================
null
];
/**
* Constructor
*
* @param string|array|\Traversable $encodingOrOptions OPTIONAL
*/
public function __construct($encodingOrOptions = null)
{
if ($encodingOrOptions !== null) {
if (static::isOptions($encodingOrOptions)) {
$this->setOptions($encodingOrOptions);
} else {
$this->setEncoding($encodingOrOptions);
}
}
}
/**
* {@inheritDoc}
*
* Returns the string $value, converting words to have an uppercase first character as necessary
*
* If the value provided is not a string, the value will remain unfiltered
*
* @param string|mixed $value
* @return string|mixed
*/
public function filter($value)
{
if (! is_string($value)) {
return $value;
}
$value = (string) $value;
if ($this->options['encoding'] !== null) {
return mb_convert_case($value, MB_CASE_TITLE, $this->options['encoding']);
}
return ucwords(strtolower($value));
}
}
================================================
FILE: src/Zend/Filter/src/UriNormalize.php
================================================
setOptions($options);
}
}
/**
* Set the default scheme to use when parsing scheme-less URIs
*
* The scheme used when parsing URIs may affect the specific object used to
* normalize the URI and thus may affect the resulting normalize URI.
*
* @param string $defaultScheme
* @return self
*/
public function setDefaultScheme($defaultScheme)
{
$this->defaultScheme = $defaultScheme;
return $this;
}
/**
* Set a URI scheme to enforce on schemeless URIs
*
* This allows forcing input values such as 'www.example.com/foo' into
* 'http://www.example.com/foo'.
*
* This should be used with caution, as a standard-compliant URI parser
* would regard 'www.example.com' in the above input URI to be the path and
* not host part of the URI. While this option can assist in solving
* real-world user mishaps, it may yield unexpected results at times.
*
* @param string $enforcedScheme
* @return self
*/
public function setEnforcedScheme($enforcedScheme)
{
$this->enforcedScheme = $enforcedScheme;
return $this;
}
/**
* Filter the URL by normalizing it and applying a default scheme if set
*
* @param string $value
* @return string
*/
public function filter($value)
{
if (! is_scalar($value)) {
return $value;
}
$value = (string) $value;
$defaultScheme = $this->defaultScheme ?: $this->enforcedScheme;
// Reset default scheme if it is not a known scheme
if (! UriFactory::getRegisteredSchemeClass($defaultScheme)) {
$defaultScheme = null;
}
try {
$uri = UriFactory::factory($value, $defaultScheme);
if ($this->enforcedScheme && ! $uri->getScheme()) {
$this->enforceScheme($uri);
}
} catch (UriException) {
// We are unable to parse / enfore scheme with the given config and input
return $value;
}
$uri->normalize();
if (! $uri->isValid()) {
return $value;
}
return $uri->toString();
}
/**
* Enforce the defined scheme on the URI
*
* This will also adjust the host and path parts of the URI as expected in
* the case of scheme-less network URIs
*
* @param Uri $uri
*/
protected function enforceScheme(Uri $uri)
{
$path = $uri->getPath();
if (str_contains($path, '/')) {
[$host, $path] = explode('/', $path, 2);
$path = '/' . $path;
} else {
$host = $path;
$path = '';
}
// We have nothing to do if we have no host
if (! $host) {
return;
}
$uri->setScheme($this->enforcedScheme)
->setHost($host)
->setPath($path);
}
}
================================================
FILE: src/Zend/Filter/src/Whitelist.php
================================================
setOptions($options);
}
}
/**
* Determine whether the in_array() call should be "strict" or not. See in_array docs.
*
* @param bool $strict
*/
public function setStrict($strict = true)
{
$this->strict = (bool) $strict;
}
/**
* Returns whether the in_array() call should be "strict" or not. See in_array docs.
*
* @return boolean
*/
public function getStrict()
{
return $this->strict;
}
/**
* Set the list of items to white-list.
*
* @param array|Traversable $list
*/
public function setList($list = [])
{
if (! is_array($list)) {
$list = ArrayUtils::iteratorToArray($list);
}
$this->list = $list;
}
/**
* Get the list of items to white-list
*
* @return array
*/
public function getList()
{
return $this->list;
}
/**
* {@inheritDoc}
*
* Will return $value if its present in the white-list. If $value is rejected then it will return null.
*/
public function filter($value)
{
return in_array($value, $this->getList(), $this->getStrict()) ? $value : null;
}
}
================================================
FILE: src/Zend/Filter/src/Word/AbstractSeparator.php
================================================
setSeparator($separator);
}
/**
* Sets a new separator
*
* @param string $separator Separator
* @return self
* @throws Exception\InvalidArgumentException
*/
public function setSeparator($separator)
{
if (! is_string($separator)) {
throw new Exception\InvalidArgumentException('"' . $separator . '" is not a valid separator.');
}
$this->separator = $separator;
return $this;
}
/**
* Returns the actual set separator
*
* @return string
*/
public function getSeparator()
{
return $this->separator;
}
}
================================================
FILE: src/Zend/Filter/src/Word/CamelCaseToDash.php
================================================
separator . '\1', $this->separator . '\1'];
} else {
$pattern = ['#(?<=(?:[A-Z]))([A-Z]+)([A-Z][a-z])#', '#(?<=(?:[a-z0-9]))([A-Z])#'];
$replacement = ['\1' . $this->separator . '\2', $this->separator . '\1'];
}
return preg_replace($pattern, $replacement, $value);
}
}
================================================
FILE: src/Zend/Filter/src/Word/CamelCaseToUnderscore.php
================================================
separator, $value);
}
}
================================================
FILE: src/Zend/Filter/src/Word/DashToUnderscore.php
================================================
separator, '#');
if (StringUtils::hasPcreUnicodeSupport()) {
$patterns = [
'#(' . $pregQuotedSeparator.')(\P{Z}{1})#u',
'#(^\P{Z}{1})#u',
];
if (! extension_loaded('mbstring')) {
$replacements = [
// @codingStandardsIgnoreStart
static function ($matches) {
return strtoupper($matches[2]);
},
static function ($matches) {
return strtoupper($matches[1]);
},
// @codingStandardsIgnoreEnd
];
} else {
$replacements = [
// @codingStandardsIgnoreStart
static function ($matches) {
return mb_strtoupper($matches[2], 'UTF-8');
},
static function ($matches) {
return mb_strtoupper($matches[1], 'UTF-8');
},
// @codingStandardsIgnoreEnd
];
}
} else {
$patterns = [
'#(' . $pregQuotedSeparator.')([\S]{1})#',
'#(^[\S]{1})#',
];
$replacements = [
// @codingStandardsIgnoreStart
static function ($matches) {
return strtoupper($matches[2]);
},
static function ($matches) {
return strtoupper($matches[1]);
},
// @codingStandardsIgnoreEnd
];
}
$filtered = $value;
foreach ($patterns as $index => $pattern) {
$filtered = preg_replace_callback($pattern, $replacements[$index], $filtered);
}
return $filtered;
}
}
================================================
FILE: src/Zend/Filter/src/Word/SeparatorToDash.php
================================================
setSearchSeparator($searchSeparator);
$this->setReplacementSeparator($replacementSeparator);
}
/**
* Sets a new separator to search for
*
* @param string $separator Separator to search for
* @return self
*/
public function setSearchSeparator($separator)
{
$this->searchSeparator = $separator;
return $this;
}
/**
* Returns the actual set separator to search for
*
* @return string
*/
public function getSearchSeparator()
{
return $this->searchSeparator;
}
/**
* Sets a new separator which replaces the searched one
*
* @param string $separator Separator which replaces the searched one
* @return self
*/
public function setReplacementSeparator($separator)
{
$this->replacementSeparator = $separator;
return $this;
}
/**
* Returns the actual set separator which replaces the searched one
*
* @return string
*/
public function getReplacementSeparator()
{
return $this->replacementSeparator;
}
/**
* Defined by Zend\Filter\Filter
*
* Returns the string $value, replacing the searched separators with the defined ones
*
* @param string|array $value
* @return string|array
*/
public function filter($value)
{
if (! is_scalar($value) && ! is_array($value)) {
return $value;
}
if ($this->searchSeparator === null) {
throw new Exception\RuntimeException('You must provide a search separator for this filter to work.');
}
$pattern = '#' . preg_quote($this->searchSeparator, '#') . '#';
return preg_replace($pattern, $this->replacementSeparator, $value);
}
}
================================================
FILE: src/Zend/Filter/src/Word/Service/SeparatorToSeparatorFactory.php
================================================
creationOptions = $creationOptions;
}
/**
* {@inheritDoc}
*/
public function __invoke(ContainerInterface $container, $requestedName, ?array $options = null)
{
return new SeparatorToSeparator(
$options['search_separator'] ?? ' ',
$options['replacement_separator'] ?? '-'
);
}
public function createService(ServiceLocatorInterface $serviceLocator)
{
return $this($serviceLocator, self::class, $this->creationOptions);
}
public function setCreationOptions(array $options)
{
$this->creationOptions = $options;
}
}
================================================
FILE: src/Zend/Filter/src/Word/UnderscoreToCamelCase.php
================================================
getParam('annotations');
if (! $annotations->hasAnnotation('Zend\Form\Annotation\Name')) {
return false;
}
foreach ($annotations as $annotation) {
if (! $annotation instanceof Name) {
continue;
}
return $annotation->getName();
}
return false;
}
/**
* Discover the fallback name via reflection
*
* @param \Zend\EventManager\EventInterface $e
* @return string
*/
public function discoverFallbackName($e)
{
$reflection = $e->getParam('reflection');
if ($reflection instanceof ReflectionClass) {
return $reflection->getShortName();
}
return $reflection->getName();
}
}
================================================
FILE: src/Zend/Form/src/Annotation/AbstractArrayAnnotation.php
================================================
value = $data['value'];
}
}
================================================
FILE: src/Zend/Form/src/Annotation/AbstractArrayOrStringAnnotation.php
================================================
value = $data['value'];
}
}
================================================
FILE: src/Zend/Form/src/Annotation/AbstractStringAnnotation.php
================================================
value = $data['value'];
}
}
================================================
FILE: src/Zend/Form/src/Annotation/AllowEmpty.php
================================================
filter($allowEmpty);
}
$this->allowEmpty = $allowEmpty;
}
/**
* Get value of required flag
*
* @return bool
*/
public function getAllowEmpty()
{
return $this->allowEmpty;
}
}
================================================
FILE: src/Zend/Form/src/Annotation/AnnotationBuilder.php
================================================
formFactory = $formFactory;
return $this;
}
/**
* Set annotation manager to use when building form from annotations
*
* @param AnnotationManager $annotationManager
* @return AnnotationBuilder
*/
public function setAnnotationManager(AnnotationManager $annotationManager)
{
$parser = $this->getAnnotationParser();
foreach ($this->defaultAnnotations as $annotationName) {
$class = __NAMESPACE__ . '\\' . $annotationName;
$parser->registerAnnotation($class);
}
$annotationManager->attach($parser);
$this->annotationManager = $annotationManager;
return $this;
}
/**
* Set event manager instance
*
* @param EventManagerInterface $events
* @return AnnotationBuilder
*/
public function setEventManager(EventManagerInterface $events)
{
$events->setIdentifiers([
__CLASS__,
get_class($this),
]);
(new ElementAnnotationsListener())->attach($events);
(new FormAnnotationsListener())->attach($events);
$this->events = $events;
return $this;
}
/**
* Retrieve form factory
*
* Lazy-loads the default form factory if none is currently set.
*
* @return Factory
*/
public function getFormFactory()
{
if ($this->formFactory) {
return $this->formFactory;
}
$this->formFactory = new Factory();
return $this->formFactory;
}
/**
* Retrieve annotation manager
*
* If none is currently set, creates one with default annotations.
*
* @return AnnotationManager
*/
public function getAnnotationManager()
{
if ($this->annotationManager) {
return $this->annotationManager;
}
$this->setAnnotationManager(new AnnotationManager());
return $this->annotationManager;
}
/**
* Get event manager
*
* @return EventManagerInterface
*/
public function getEventManager()
{
if (null === $this->events) {
$this->setEventManager(new EventManager());
}
return $this->events;
}
/**
* Creates and returns a form specification for use with a factory
*
* Parses the object provided, and processes annotations for the class and
* all properties. Information from annotations is then used to create
* specifications for a form, its elements, and its input filter.
*
* @param string|object $entity Either an instance or a valid class name for an entity
* @throws Exception\InvalidArgumentException if $entity is not an object or class name
* @return ArrayObject
*/
public function getFormSpecification($entity)
{
if (! is_object($entity)) {
if ((is_string($entity) && (! class_exists($entity))) // non-existent class
|| (! is_string($entity)) // not an object or string
) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects an object or valid class name; received "%s"',
__METHOD__,
var_export($entity, 1)
));
}
}
$this->entity = $entity;
$annotationManager = $this->getAnnotationManager();
$formSpec = new ArrayObject();
$filterSpec = new ArrayObject();
$reflection = new ClassReflection($entity);
$annotations = $reflection->getAnnotations($annotationManager);
if ($annotations instanceof AnnotationCollection) {
$this->configureForm($annotations, $reflection, $formSpec, $filterSpec);
}
foreach ($reflection->getProperties() as $property) {
$annotations = $property->getAnnotations($annotationManager);
if ($annotations instanceof AnnotationCollection) {
$this->configureElement($annotations, $property, $formSpec, $filterSpec);
}
}
if (! isset($formSpec['input_filter'])) {
$formSpec['input_filter'] = $filterSpec;
} elseif (is_array($formSpec['input_filter'])) {
$formSpec['input_filter'] = ArrayUtils::merge($filterSpec->getArrayCopy(), $formSpec['input_filter']);
}
return $formSpec;
}
/**
* Create a form from an object.
*
* @param string|object $entity
* @return \Zend\Form\Form
*/
public function createForm($entity)
{
$formSpec = ArrayUtils::iteratorToArray($this->getFormSpecification($entity));
$formFactory = $this->getFormFactory();
return $formFactory->createForm($formSpec);
}
/**
* Get the entity used to construct the form.
*
* @return object
*/
public function getEntity()
{
return $this->entity;
}
/**
* Configure the form specification from annotations
*
* @param AnnotationCollection $annotations
* @param ClassReflection $reflection
* @param ArrayObject $formSpec
* @param ArrayObject $filterSpec
* @return void
* @triggers discoverName
* @triggers configureForm
*/
protected function configureForm($annotations, $reflection, $formSpec, $filterSpec)
{
$name = $this->discoverName($annotations, $reflection);
$formSpec['name'] = $name;
$formSpec['attributes'] = [];
$formSpec['elements'] = [];
$formSpec['fieldsets'] = [];
$events = $this->getEventManager();
foreach ($annotations as $annotation) {
$events->trigger(__FUNCTION__, $this, [
'annotation' => $annotation,
'name' => $name,
'formSpec' => $formSpec,
'filterSpec' => $filterSpec,
]);
}
}
/**
* Configure an element from annotations
*
* @param AnnotationCollection $annotations
* @param \Zend\Code\Reflection\PropertyReflection $reflection
* @param ArrayObject $formSpec
* @param ArrayObject $filterSpec
* @return void
* @triggers checkForExclude
* @triggers discoverName
* @triggers configureElement
*/
protected function configureElement($annotations, $reflection, $formSpec, $filterSpec)
{
// If the element is marked as exclude, return early
if ($this->checkForExclude($annotations)) {
return;
}
$events = $this->getEventManager();
$name = $this->discoverName($annotations, $reflection);
$elementSpec = new ArrayObject([
'flags' => [],
'spec' => [
'name' => $name
],
]);
$inputSpec = new ArrayObject([
'name' => $name,
]);
$params = [
'name' => $name,
'elementSpec' => $elementSpec,
'inputSpec' => $inputSpec,
'formSpec' => $formSpec,
'filterSpec' => $filterSpec,
];
foreach ($annotations as $annotation) {
$params['annotation'] = $annotation;
$events->trigger(__FUNCTION__, $this, $params);
}
// Since "type" is a reserved name in the filter specification,
// we need to add the specification without the name as the key.
// In all other cases, though, the name is fine.
if ($params['inputSpec']->count() > 1) {
if ($name === 'type') {
$filterSpec[] = $params['inputSpec'];
} else {
$filterSpec[$name] = $params['inputSpec'];
}
}
$elementSpec = $params['elementSpec'];
$type = (isset($elementSpec['spec']['type']))
? $elementSpec['spec']['type']
: 'Zend\Form\Element';
// Compose as a fieldset or an element, based on specification type.
// If preserve defined order is true, all elements are composed as elements to keep their ordering
if (! $this->preserveDefinedOrder() && is_subclass_of($type, 'Zend\Form\FieldsetInterface')) {
if (! isset($formSpec['fieldsets'])) {
$formSpec['fieldsets'] = [];
}
$formSpec['fieldsets'][] = $elementSpec;
} else {
if (! isset($formSpec['elements'])) {
$formSpec['elements'] = [];
}
$formSpec['elements'][] = $elementSpec;
}
}
/**
* @param bool $preserveDefinedOrder
* @return $this
*/
public function setPreserveDefinedOrder($preserveDefinedOrder)
{
$this->preserveDefinedOrder = (bool) $preserveDefinedOrder;
return $this;
}
/**
* @return bool
*/
public function preserveDefinedOrder()
{
return $this->preserveDefinedOrder;
}
/**
* Discover the name of the given form or element
*
* @param AnnotationCollection $annotations
* @param \Reflector $reflection
* @return string
*/
protected function discoverName($annotations, $reflection)
{
$event = new Event();
$event->setName(__FUNCTION__);
$event->setTarget($this);
$event->setParams([
'annotations' => $annotations,
'reflection' => $reflection,
]);
$results = $this->getEventManager()->triggerEventUntil(
function ($r) {
return (is_string($r) && ! empty($r));
},
$event
);
return $results->last();
}
/**
* Determine if an element is marked to exclude from the definitions
*
* @param AnnotationCollection $annotations
* @return true|false
*/
protected function checkForExclude($annotations)
{
$event = new Event();
$event->setName(__FUNCTION__);
$event->setTarget($this);
$event->setParams(['annotations' => $annotations]);
$results = $this->getEventManager()->triggerEventUntil(
function ($r) {
return (true === $r);
},
$event
);
return (bool) $results->last();
}
/**
* @return \Zend\Code\Annotation\Parser\DoctrineAnnotationParser
*/
public function getAnnotationParser()
{
if (null === $this->annotationParser) {
$this->annotationParser = new Parser\DoctrineAnnotationParser();
}
return $this->annotationParser;
}
/**
* Checks if the object has this class as one of its parents
*
* @see https://bugs.php.net/bug.php?id=53727
* @see https://github.com/zendframework/zf2/pull/1807
*
* @deprecated since zf 2.3 requires PHP >= 5.3.23
*
* @param string $className
* @param string $type
* @return bool
*/
protected static function isSubclassOf($className, $type)
{
return is_subclass_of($className, $type);
}
}
================================================
FILE: src/Zend/Form/src/Annotation/AnnotationBuilderFactory.php
================================================
get('EventManager');
$annotationBuilder->setEventManager($eventManager);
$this->injectFactory($annotationBuilder->getFormFactory(), $container);
$config = $this->marshalConfig($container);
if (isset($config['preserve_defined_order'])) {
$annotationBuilder->setPreserveDefinedOrder($config['preserve_defined_order']);
}
$this->injectAnnotations($config, $annotationBuilder);
$this->injectListeners($config, $eventManager, $container);
return $annotationBuilder;
}
/**
* Create and return AnnotationBuilder instance
*
* For use with zend-servicemanager v2; proxies to __invoke().
*
* @param ServiceLocatorInterface $container
* @return AnnotationBuilder
*/
public function createService(ServiceLocatorInterface $container)
{
return $this($container, AnnotationBuilder::class);
}
/**
* Marshal annotation builder configuration, if any.
*
* Looks for the `config` service in the container, returning an empty array
* if not found.
*
* If found, checks for a `form_annotation_builder` entry, returning an empty
* array if not found or not an array.
*
* Otherwise, returns the `form_annotation_builder` array.
*
* @param ContainerInterface $container
* @return array
*/
private function marshalConfig(ContainerInterface $container)
{
if (! $container->has('config')) {
return [];
}
$config = $container->get('config');
$config = $config['form_annotation_builder'] ?? [];
return is_array($config) ? $config : [];
}
/**
* Inject annotations from configuration, if any.
*
* @param array $config
* @param AnnotationBuilder $builder
* @return void
*/
private function injectAnnotations(array $config, AnnotationBuilder $builder)
{
if (! isset($config['annotations'])) {
return;
}
$parser = $builder->getAnnotationParser();
foreach ($config['annotations'] as $fullyQualifiedClassName) {
$parser->registerAnnotation($fullyQualifiedClassName);
}
}
/**
* Inject event listeners from configuration, if any.
*
* Loops through the 'listeners' array, and:
*
* - attempts to fetch it from the container
* - if the fetched instance is not a `ListenerAggregate`, raises an exception
* - otherwise attaches it to the event manager
*
* @param array $config
* @param EventManagerInterface $events
* @param ContainerInterface $container
* @return void
* @throws ServiceNotCreatedException if any listener is not an event listener
* aggregate.
*/
private function injectListeners(array $config, EventManagerInterface $events, ContainerInterface $container)
{
if (! isset($config['listeners'])) {
return;
}
foreach ($config['listeners'] as $listenerName) {
$listener = $container->get($listenerName);
if (! $listener instanceof ListenerAggregateInterface) {
throw new ServiceNotCreatedException(sprintf('Invalid event listener (%s) provided', $listenerName));
}
$listener->attach($events);
}
}
/**
* Inject the annotation builder's factory instance with the FormElementManager.
*
* Also injects the factory with the InputFilterManager if present.
*
* @param Factory $factory
* @param ContainerInterface $container
*/
private function injectFactory(Factory $factory, ContainerInterface $container)
{
$factory->setFormElementManager($container->get('FormElementManager'));
if ($container->has('InputFilterManager')) {
$inputFilters = $container->get('InputFilterManager');
$factory->getInputFilterFactory()->setInputFilterManager($inputFilters);
}
}
}
================================================
FILE: src/Zend/Form/src/Annotation/Attributes.php
================================================
value;
}
}
================================================
FILE: src/Zend/Form/src/Annotation/ComposedObject.php
================================================
value)) {
return $this->value['target_object'];
}
return $this->value;
}
/**
* Is this composed object a collection or not
*
* @return bool
*/
public function isCollection()
{
return is_array($this->value) && isset($this->value['is_collection']) && $this->value['is_collection'];
}
/**
* Retrieve the options for the composed object
*
* @return array
*/
public function getOptions()
{
return is_array($this->value) && isset($this->value['options']) ? $this->value['options'] : [];
}
}
================================================
FILE: src/Zend/Form/src/Annotation/ContinueIfEmpty.php
================================================
filter($continueIfEmpty);
}
$this->continueIfEmpty = $continueIfEmpty;
}
/**
* Get value of required flag
*
* @return bool
*/
public function getContinueIfEmpty()
{
return $this->continueIfEmpty;
}
}
================================================
FILE: src/Zend/Form/src/Annotation/ElementAnnotationsListener.php
================================================
listeners[] = $events->attach('configureElement', [$this, 'handleAllowEmptyAnnotation'], $priority);
$this->listeners[] = $events->attach('configureElement', [$this, 'handleAttributesAnnotation'], $priority);
$this->listeners[] = $events->attach('configureElement', [$this, 'handleComposedObjectAnnotation'], $priority);
$this->listeners[] = $events->attach('configureElement', [$this, 'handleContinueIfEmptyAnnotation'], $priority);
$this->listeners[] = $events->attach('configureElement', [$this, 'handleErrorMessageAnnotation'], $priority);
$this->listeners[] = $events->attach('configureElement', [$this, 'handleFilterAnnotation'], $priority);
$this->listeners[] = $events->attach('configureElement', [$this, 'handleFlagsAnnotation'], $priority);
$this->listeners[] = $events->attach('configureElement', [$this, 'handleHydratorAnnotation'], $priority);
$this->listeners[] = $events->attach('configureElement', [$this, 'handleInputAnnotation'], $priority);
$this->listeners[] = $events->attach('configureElement', [$this, 'handleObjectAnnotation'], $priority);
$this->listeners[] = $events->attach('configureElement', [$this, 'handleOptionsAnnotation'], $priority);
$this->listeners[] = $events->attach('configureElement', [$this, 'handleRequiredAnnotation'], $priority);
$this->listeners[] = $events->attach('configureElement', [$this, 'handleTypeAnnotation'], $priority);
$this->listeners[] = $events->attach('configureElement', [$this, 'handleValidatorAnnotation'], $priority);
$this->listeners[] = $events->attach('discoverName', [$this, 'handleNameAnnotation'], $priority);
$this->listeners[] = $events->attach('discoverName', [$this, 'discoverFallbackName'], $priority);
$this->listeners[] = $events->attach('checkForExclude', [$this, 'handleExcludeAnnotation'], $priority);
}
/**
* Handle the AllowEmpty annotation
*
* Sets the allow_empty flag on the input specification array.
*
* @param \Zend\EventManager\EventInterface $e
* @return void
*/
public function handleAllowEmptyAnnotation($e)
{
$annotation = $e->getParam('annotation');
if (! $annotation instanceof AllowEmpty) {
return;
}
$inputSpec = $e->getParam('inputSpec');
$inputSpec['allow_empty'] = true;
}
/**
* Handle the Attributes annotation
*
* Sets the attributes array of the element specification.
*
* @param \Zend\EventManager\EventInterface $e
* @return void
*/
public function handleAttributesAnnotation($e)
{
$annotation = $e->getParam('annotation');
if (! $annotation instanceof Attributes) {
return;
}
$elementSpec = $e->getParam('elementSpec');
if (isset($elementSpec['spec']['attributes'])) {
$elementSpec['spec']['attributes'] = array_merge(
$elementSpec['spec']['attributes'],
$annotation->getAttributes()
);
return;
}
$elementSpec['spec']['attributes'] = $annotation->getAttributes();
}
/**
* Allow creating fieldsets from composed entity properties
*
* @param \Zend\EventManager\EventInterface $e
* @return void
*/
public function handleComposedObjectAnnotation($e)
{
$annotation = $e->getParam('annotation');
if (! $annotation instanceof ComposedObject) {
return;
}
$class = $annotation->getComposedObject();
$annotationManager = $e->getTarget();
$specification = $annotationManager->getFormSpecification($class);
$name = $e->getParam('name');
$elementSpec = $e->getParam('elementSpec');
if ($annotation->isCollection()) {
// Compose specification as a fieldset into parent form/fieldset
if (! isset($specification['type'])) {
//use input filter provider fieldset so we can compose the input filter into the fieldset
//it is assumed that if someone uses a custom fieldset, they will take care of the input
//filtering themselves or consume the input_filter_spec option.
$specification['type'] = 'Zend\Form\InputFilterProviderFieldset';
}
$inputFilter = $specification['input_filter'];
if (! isset($inputFilter['type'])) {
$inputFilter['type'] = 'Zend\InputFilter\InputFilter';
}
unset($specification['input_filter']);
$elementSpec['spec']['type'] = 'Zend\Form\Element\Collection';
$elementSpec['spec']['name'] = $name;
$elementSpec['spec']['options'] = new ArrayObject($this->mergeOptions($elementSpec, $annotation));
$elementSpec['spec']['options']['target_element'] = $specification;
$elementSpec['spec']['options']['target_element']['options']['input_filter_spec'] = $inputFilter;
if (isset($specification['hydrator'])) {
$elementSpec['spec']['hydrator'] = $specification['hydrator'];
}
} else {
// Compose input filter into parent input filter
$inputFilter = $specification['input_filter'];
if (! isset($inputFilter['type'])) {
$inputFilter['type'] = 'Zend\InputFilter\InputFilter';
}
$e->setParam('inputSpec', $inputFilter);
unset($specification['input_filter']);
// Compose specification as a fieldset into parent form/fieldset
if (! isset($specification['type'])) {
$specification['type'] = 'Zend\Form\Fieldset';
}
if (isset($elementSpec['spec']['options'])) {
$specification['options'] = $specification['options'] ?? [];
$specification['options'] = array_merge($elementSpec['spec']['options'], $specification['options']);
}
// Add element spec:
$elementSpec['spec'] = $specification;
$elementSpec['spec']['name'] = $name;
$elementSpec['spec']['options'] = new ArrayObject($this->mergeOptions($elementSpec, $annotation));
}
}
/**
* Handle the ContinueIfEmpty annotation
*
* Sets the continue_if_empty flag on the input specification array.
*
* @param \Zend\EventManager\EventInterface $e
* @return void
*/
public function handleContinueIfEmptyAnnotation($e)
{
$annotation = $e->getParam('annotation');
if (! $annotation instanceof ContinueIfEmpty) {
return;
}
$inputSpec = $e->getParam('inputSpec');
$inputSpec['continue_if_empty'] = true;
}
/**
* Handle the ErrorMessage annotation
*
* Sets the error_message of the input specification.
*
* @param \Zend\EventManager\EventInterface $e
* @return void
*/
public function handleErrorMessageAnnotation($e)
{
$annotation = $e->getParam('annotation');
if (! $annotation instanceof ErrorMessage) {
return;
}
$inputSpec = $e->getParam('inputSpec');
$inputSpec['error_message'] = $annotation->getMessage();
}
/**
* Determine if the element has been marked to exclude from the definition
*
* @param \Zend\EventManager\EventInterface $e
* @return bool
*/
public function handleExcludeAnnotation($e)
{
$annotations = $e->getParam('annotations');
if ($annotations->hasAnnotation('Zend\Form\Annotation\Exclude')) {
return true;
}
return false;
}
/**
* Handle the Filter annotation
*
* Adds a filter to the filter chain specification for the input.
*
* @param \Zend\EventManager\EventInterface $e
* @return void
*/
public function handleFilterAnnotation($e)
{
$annotation = $e->getParam('annotation');
if (! $annotation instanceof Filter) {
return;
}
$inputSpec = $e->getParam('inputSpec');
if (! isset($inputSpec['filters'])) {
$inputSpec['filters'] = [];
}
$inputSpec['filters'][] = $annotation->getFilter();
}
/**
* Handle the Flags annotation
*
* Sets the element flags in the specification (used typically for setting
* priority).
*
* @param \Zend\EventManager\EventInterface $e
* @return void
*/
public function handleFlagsAnnotation($e)
{
$annotation = $e->getParam('annotation');
if (! $annotation instanceof Flags) {
return;
}
$elementSpec = $e->getParam('elementSpec');
$elementSpec['flags'] = $annotation->getFlags();
}
/**
* Handle the Hydrator annotation
*
* Sets the hydrator class to use in the fieldset specification.
*
* @param \Zend\EventManager\EventInterface $e
* @return void
*/
public function handleHydratorAnnotation($e)
{
$annotation = $e->getParam('annotation');
if (! $annotation instanceof Hydrator) {
return;
}
$elementSpec = $e->getParam('elementSpec');
$elementSpec['spec']['hydrator'] = $annotation->getHydrator();
}
/**
* Handle the Input annotation
*
* Sets the filter specification for the current element to the specified
* input class name.
*
* @param \Zend\EventManager\EventInterface $e
* @return void
*/
public function handleInputAnnotation($e)
{
$annotation = $e->getParam('annotation');
if (! $annotation instanceof Input) {
return;
}
$inputSpec = $e->getParam('inputSpec');
$inputSpec['type'] = $annotation->getInput();
}
/**
* Handle the Object and Instance annotations
*
* Sets the object to bind to the form or fieldset
*
* @param \Zend\EventManager\EventInterface $e
* @return void
*/
public function handleObjectAnnotation($e)
{
$annotation = $e->getParam('annotation');
// Only need to typehint on Instance, as Object extends it
if (! $annotation instanceof Instance) {
return;
}
$elementSpec = $e->getParam('elementSpec');
$elementSpec['spec']['object'] = $annotation->getObject();
}
/**
* Handle the Options annotation
*
* Sets the element options in the specification.
*
* @param \Zend\EventManager\EventInterface $e
* @return void
*/
public function handleOptionsAnnotation($e)
{
$annotation = $e->getParam('annotation');
if (! $annotation instanceof Options) {
return;
}
$elementSpec = $e->getParam('elementSpec');
$elementSpec['spec']['options'] = $this->mergeOptions($elementSpec, $annotation);
}
/**
* Handle the Required annotation
*
* Sets the required flag on the input based on the annotation value.
*
* @param \Zend\EventManager\EventInterface $e
* @return void
*/
public function handleRequiredAnnotation($e)
{
$annotation = $e->getParam('annotation');
if (! $annotation instanceof Required) {
return;
}
$required = (bool) $annotation->getRequired();
$inputSpec = $e->getParam('inputSpec');
$inputSpec['required'] = $required;
if ($required) {
$elementSpec = $e->getParam('elementSpec');
if (! isset($elementSpec['spec']['attributes'])) {
$elementSpec['spec']['attributes'] = [];
}
$elementSpec['spec']['attributes']['required'] = 'required';
}
}
/**
* Handle the Type annotation
*
* Sets the element class type to use in the element specification.
*
* @param \Zend\EventManager\EventInterface $e
* @return void
*/
public function handleTypeAnnotation($e)
{
$annotation = $e->getParam('annotation');
if (! $annotation instanceof Type) {
return;
}
$elementSpec = $e->getParam('elementSpec');
$elementSpec['spec']['type'] = $annotation->getType();
}
/**
* Handle the Validator annotation
*
* Adds a validator to the validator chain of the input specification.
*
* @param \Zend\EventManager\EventInterface $e
* @return void
*/
public function handleValidatorAnnotation($e)
{
$annotation = $e->getParam('annotation');
if (! $annotation instanceof Validator) {
return;
}
$inputSpec = $e->getParam('inputSpec');
if (! isset($inputSpec['validators'])) {
$inputSpec['validators'] = [];
}
$inputSpec['validators'][] = $annotation->getValidator();
}
/**
* @param array|\ArrayAccess $elementSpec
* @param ComposedObject|Options $annotation
*
* @return array
*/
private function mergeOptions($elementSpec, $annotation)
{
if (isset($elementSpec['spec']['options'])) {
if (is_array($elementSpec['spec']['options'])) {
return array_merge($elementSpec['spec']['options'], $annotation->getOptions());
}
if ($elementSpec['spec']['options'] instanceof ArrayObject) {
return array_merge($elementSpec['spec']['options']->getArrayCopy(), $annotation->getOptions());
}
}
return $annotation->getOptions();
}
}
================================================
FILE: src/Zend/Form/src/Annotation/ErrorMessage.php
================================================
value;
}
}
================================================
FILE: src/Zend/Form/src/Annotation/Exclude.php
================================================
value;
}
}
================================================
FILE: src/Zend/Form/src/Annotation/Flags.php
================================================
value;
}
}
================================================
FILE: src/Zend/Form/src/Annotation/FormAnnotationsListener.php
================================================
listeners[] = $events->attach('configureForm', [$this, 'handleAttributesAnnotation'], $priority);
$this->listeners[] = $events->attach('configureForm', [$this, 'handleFlagsAnnotation'], $priority);
$this->listeners[] = $events->attach('configureForm', [$this, 'handleHydratorAnnotation'], $priority);
$this->listeners[] = $events->attach('configureForm', [$this, 'handleInputFilterAnnotation'], $priority);
$this->listeners[] = $events->attach('configureForm', [$this, 'handleObjectAnnotation'], $priority);
$this->listeners[] = $events->attach('configureForm', [$this, 'handleOptionsAnnotation'], $priority);
$this->listeners[] = $events->attach('configureForm', [$this, 'handleTypeAnnotation'], $priority);
$this->listeners[] = $events->attach('configureForm', [$this, 'handleValidationGroupAnnotation'], $priority);
$this->listeners[] = $events->attach('discoverName', [$this, 'handleNameAnnotation'], $priority);
$this->listeners[] = $events->attach('discoverName', [$this, 'discoverFallbackName'], $priority);
}
/**
* Handle the Attributes annotation
*
* Sets the attributes key of the form specification.
*
* @param \Zend\EventManager\EventInterface $e
* @return void
*/
public function handleAttributesAnnotation($e)
{
$annotation = $e->getParam('annotation');
if (! $annotation instanceof Attributes) {
return;
}
$formSpec = $e->getParam('formSpec');
$formSpec['attributes'] = $annotation->getAttributes();
}
/**
* Handle the Flags annotation
*
* Sets the flags key of the form specification.
*
* @param \Zend\EventManager\EventInterface $e
* @return void
*/
public function handleFlagsAnnotation($e)
{
$annotation = $e->getParam('annotation');
if (! $annotation instanceof Flags) {
return;
}
$formSpec = $e->getParam('formSpec');
$formSpec['flags'] = $annotation->getFlags();
}
/**
* Handle the Hydrator annotation
*
* Sets the hydrator class to use in the form specification.
*
* @param \Zend\EventManager\EventInterface $e
* @return void
*/
public function handleHydratorAnnotation($e)
{
$annotation = $e->getParam('annotation');
if (! $annotation instanceof Hydrator) {
return;
}
$formSpec = $e->getParam('formSpec');
$formSpec['hydrator'] = $annotation->getHydrator();
}
/**
* Handle the InputFilter annotation
*
* Sets the input filter class to use in the form specification.
*
* @param \Zend\EventManager\EventInterface $e
* @return void
*/
public function handleInputFilterAnnotation($e)
{
$annotation = $e->getParam('annotation');
if (! $annotation instanceof InputFilter) {
return;
}
$formSpec = $e->getParam('formSpec');
$formSpec['input_filter'] = $annotation->getInputFilter();
}
/**
* Handle the Object and Instance annotations
*
* Sets the object to bind to the form or fieldset
*
* @param \Zend\EventManager\EventInterface $e
* @return void
*/
public function handleObjectAnnotation($e)
{
$annotation = $e->getParam('annotation');
// Only need to typehint on Instance, as Object extends it
if (! $annotation instanceof Instance) {
return;
}
$formSpec = $e->getParam('formSpec');
$formSpec['object'] = $annotation->getObject();
}
/**
* Handle the Options annotation
*
* Sets the options key of the form specification.
*
* @param \Zend\EventManager\EventInterface $e
* @return void
*/
public function handleOptionsAnnotation($e)
{
$annotation = $e->getParam('annotation');
if (! $annotation instanceof Options) {
return;
}
$formSpec = $e->getParam('formSpec');
$formSpec['options'] = $annotation->getOptions();
}
/**
* Handle the Type annotation
*
* Sets the form class to use in the form specification.
*
* @param \Zend\EventManager\EventInterface $e
* @return void
*/
public function handleTypeAnnotation($e)
{
$annotation = $e->getParam('annotation');
if (! $annotation instanceof Type) {
return;
}
$formSpec = $e->getParam('formSpec');
$formSpec['type'] = $annotation->getType();
}
/**
* Handle the ValidationGroup annotation
*
* Sets the validation group to use in the form specification.
*
* @param \Zend\EventManager\EventInterface $e
* @return void
*/
public function handleValidationGroupAnnotation($e)
{
$annotation = $e->getParam('annotation');
if (! $annotation instanceof ValidationGroup) {
return;
}
$formSpec = $e->getParam('formSpec');
$formSpec['validation_group'] = $annotation->getValidationGroup();
}
}
================================================
FILE: src/Zend/Form/src/Annotation/Hydrator.php
================================================
value;
}
}
================================================
FILE: src/Zend/Form/src/Annotation/Input.php
================================================
value;
}
}
================================================
FILE: src/Zend/Form/src/Annotation/InputFilter.php
================================================
value;
}
}
================================================
FILE: src/Zend/Form/src/Annotation/Instance.php
================================================
value;
}
}
================================================
FILE: src/Zend/Form/src/Annotation/Name.php
================================================
value;
}
}
================================================
FILE: src/Zend/Form/src/Annotation/Options.php
================================================
value;
}
}
================================================
FILE: src/Zend/Form/src/Annotation/Required.php
================================================
filter($required);
}
$this->required = $required;
}
/**
* Get value of required flag
*
* @return bool
*/
public function getRequired()
{
return $this->required;
}
}
================================================
FILE: src/Zend/Form/src/Annotation/Type.php
================================================
value;
}
}
================================================
FILE: src/Zend/Form/src/Annotation/ValidationGroup.php
================================================
value;
}
}
================================================
FILE: src/Zend/Form/src/Annotation/Validator.php
================================================
value;
}
}
================================================
FILE: src/Zend/Form/src/ConfigProvider.php
================================================
$this->getDependencyConfig(),
'view_helpers' => $this->getViewHelperConfig(),
];
}
/**
* Return application-level dependency configuration.
*
* @return array
*/
public function getDependencyConfig()
{
return [
'abstract_factories' => [
FormAbstractServiceFactory::class,
],
'aliases' => [
'Zend\Form\Annotation\FormAnnotationBuilder' => 'FormAnnotationBuilder',
Annotation\AnnotationBuilder::class => 'FormAnnotationBuilder',
FormElementManager::class => 'FormElementManager',
],
'factories' => [
'FormAnnotationBuilder' => Annotation\AnnotationBuilderFactory::class,
'FormElementManager' => FormElementManagerFactory::class,
],
];
}
/**
* Return zend-form helper configuration.
*
* Obsoletes View\HelperConfig.
*
* @return array
*/
public function getViewHelperConfig()
{
return [
'aliases' => [
'form' => View\Helper\Form::class,
'Form' => View\Helper\Form::class,
'formbutton' => View\Helper\FormButton::class,
'form_button' => View\Helper\FormButton::class,
'formButton' => View\Helper\FormButton::class,
'FormButton' => View\Helper\FormButton::class,
'formcaptcha' => View\Helper\FormCaptcha::class,
'form_captcha' => View\Helper\FormCaptcha::class,
'formCaptcha' => View\Helper\FormCaptcha::class,
'FormCaptcha' => View\Helper\FormCaptcha::class,
'captchadumb' => View\Helper\Captcha\Dumb::class,
'captcha_dumb' => View\Helper\Captcha\Dumb::class,
// weird alias used by Zend\Captcha
'captcha/dumb' => View\Helper\Captcha\Dumb::class,
'CaptchaDumb' => View\Helper\Captcha\Dumb::class,
'captchaDumb' => View\Helper\Captcha\Dumb::class,
'formcaptchadumb' => View\Helper\Captcha\Dumb::class,
'form_captcha_dumb' => View\Helper\Captcha\Dumb::class,
'formCaptchaDumb' => View\Helper\Captcha\Dumb::class,
'FormCaptchaDumb' => View\Helper\Captcha\Dumb::class,
'captchafiglet' => View\Helper\Captcha\Figlet::class,
// weird alias used by Zend\Captcha
'captcha/figlet' => View\Helper\Captcha\Figlet::class,
'captcha_figlet' => View\Helper\Captcha\Figlet::class,
'captchaFiglet' => View\Helper\Captcha\Figlet::class,
'CaptchaFiglet' => View\Helper\Captcha\Figlet::class,
'formcaptchafiglet' => View\Helper\Captcha\Figlet::class,
'form_captcha_figlet' => View\Helper\Captcha\Figlet::class,
'formCaptchaFiglet' => View\Helper\Captcha\Figlet::class,
'FormCaptchaFiglet' => View\Helper\Captcha\Figlet::class,
'captchaimage' => View\Helper\Captcha\Image::class,
// weird alias used by Zend\Captcha
'captcha/image' => View\Helper\Captcha\Image::class,
'captcha_image' => View\Helper\Captcha\Image::class,
'captchaImage' => View\Helper\Captcha\Image::class,
'CaptchaImage' => View\Helper\Captcha\Image::class,
'formcaptchaimage' => View\Helper\Captcha\Image::class,
'form_captcha_image' => View\Helper\Captcha\Image::class,
'formCaptchaImage' => View\Helper\Captcha\Image::class,
'FormCaptchaImage' => View\Helper\Captcha\Image::class,
'captcharecaptcha' => View\Helper\Captcha\ReCaptcha::class,
// weird alias used by Zend\Captcha
'captcha/recaptcha' => View\Helper\Captcha\ReCaptcha::class,
'captcha_recaptcha' => View\Helper\Captcha\ReCaptcha::class,
'captchaRecaptcha' => View\Helper\Captcha\ReCaptcha::class,
'CaptchaRecaptcha' => View\Helper\Captcha\ReCaptcha::class,
'formcaptcharecaptcha' => View\Helper\Captcha\ReCaptcha::class,
'form_captcha_recaptcha' => View\Helper\Captcha\ReCaptcha::class,
'formCaptchaRecaptcha' => View\Helper\Captcha\ReCaptcha::class,
'FormCaptchaRecaptcha' => View\Helper\Captcha\ReCaptcha::class,
'formcheckbox' => View\Helper\FormCheckbox::class,
'form_checkbox' => View\Helper\FormCheckbox::class,
'formCheckbox' => View\Helper\FormCheckbox::class,
'FormCheckbox' => View\Helper\FormCheckbox::class,
'formcollection' => View\Helper\FormCollection::class,
'form_collection' => View\Helper\FormCollection::class,
'formCollection' => View\Helper\FormCollection::class,
'FormCollection' => View\Helper\FormCollection::class,
'formcolor' => View\Helper\FormColor::class,
'form_color' => View\Helper\FormColor::class,
'formColor' => View\Helper\FormColor::class,
'FormColor' => View\Helper\FormColor::class,
'formdate' => View\Helper\FormDate::class,
'form_date' => View\Helper\FormDate::class,
'formDate' => View\Helper\FormDate::class,
'FormDate' => View\Helper\FormDate::class,
'formdatetime' => View\Helper\FormDateTime::class,
'form_date_time' => View\Helper\FormDateTime::class,
'formDateTime' => View\Helper\FormDateTime::class,
'FormDateTime' => View\Helper\FormDateTime::class,
'formdatetimelocal' => View\Helper\FormDateTimeLocal::class,
'form_date_time_local' => View\Helper\FormDateTimeLocal::class,
'formDateTimeLocal' => View\Helper\FormDateTimeLocal::class,
'FormDateTimeLocal' => View\Helper\FormDateTimeLocal::class,
'formdatetimeselect' => View\Helper\FormDateTimeSelect::class,
'form_date_time_select' => View\Helper\FormDateTimeSelect::class,
'formDateTimeSelect' => View\Helper\FormDateTimeSelect::class,
'FormDateTimeSelect' => View\Helper\FormDateTimeSelect::class,
'formdateselect' => View\Helper\FormDateSelect::class,
'form_date_select' => View\Helper\FormDateSelect::class,
'formDateSelect' => View\Helper\FormDateSelect::class,
'FormDateSelect' => View\Helper\FormDateSelect::class,
'form_element' => View\Helper\FormElement::class,
'formelement' => View\Helper\FormElement::class,
'formElement' => View\Helper\FormElement::class,
'FormElement' => View\Helper\FormElement::class,
'form_element_errors' => View\Helper\FormElementErrors::class,
'formelementerrors' => View\Helper\FormElementErrors::class,
'formElementErrors' => View\Helper\FormElementErrors::class,
'FormElementErrors' => View\Helper\FormElementErrors::class,
'form_email' => View\Helper\FormEmail::class,
'formemail' => View\Helper\FormEmail::class,
'formEmail' => View\Helper\FormEmail::class,
'FormEmail' => View\Helper\FormEmail::class,
'form_file' => View\Helper\FormFile::class,
'formfile' => View\Helper\FormFile::class,
'formFile' => View\Helper\FormFile::class,
'FormFile' => View\Helper\FormFile::class,
'formfileapcprogress' => View\Helper\File\FormFileApcProgress::class,
'form_file_apc_progress' => View\Helper\File\FormFileApcProgress::class,
'formFileApcProgress' => View\Helper\File\FormFileApcProgress::class,
'FormFileApcProgress' => View\Helper\File\FormFileApcProgress::class,
'formfilesessionprogress' => View\Helper\File\FormFileSessionProgress::class,
'form_file_session_progress' => View\Helper\File\FormFileSessionProgress::class,
'formFileSessionProgress' => View\Helper\File\FormFileSessionProgress::class,
'FormFileSessionProgress' => View\Helper\File\FormFileSessionProgress::class,
'formfileuploadprogress' => View\Helper\File\FormFileUploadProgress::class,
'form_file_upload_progress' => View\Helper\File\FormFileUploadProgress::class,
'formFileUploadProgress' => View\Helper\File\FormFileUploadProgress::class,
'FormFileUploadProgress' => View\Helper\File\FormFileUploadProgress::class,
'formhidden' => View\Helper\FormHidden::class,
'form_hidden' => View\Helper\FormHidden::class,
'formHidden' => View\Helper\FormHidden::class,
'FormHidden' => View\Helper\FormHidden::class,
'formimage' => View\Helper\FormImage::class,
'form_image' => View\Helper\FormImage::class,
'formImage' => View\Helper\FormImage::class,
'FormImage' => View\Helper\FormImage::class,
'forminput' => View\Helper\FormInput::class,
'form_input' => View\Helper\FormInput::class,
'formInput' => View\Helper\FormInput::class,
'FormInput' => View\Helper\FormInput::class,
'formlabel' => View\Helper\FormLabel::class,
'form_label' => View\Helper\FormLabel::class,
'formLabel' => View\Helper\FormLabel::class,
'FormLabel' => View\Helper\FormLabel::class,
'formmonth' => View\Helper\FormMonth::class,
'form_month' => View\Helper\FormMonth::class,
'formMonth' => View\Helper\FormMonth::class,
'FormMonth' => View\Helper\FormMonth::class,
'formmonthselect' => View\Helper\FormMonthSelect::class,
'form_month_select' => View\Helper\FormMonthSelect::class,
'formMonthSelect' => View\Helper\FormMonthSelect::class,
'FormMonthSelect' => View\Helper\FormMonthSelect::class,
'formmulticheckbox' => View\Helper\FormMultiCheckbox::class,
'form_multi_checkbox' => View\Helper\FormMultiCheckbox::class,
'formMultiCheckbox' => View\Helper\FormMultiCheckbox::class,
'FormMultiCheckbox' => View\Helper\FormMultiCheckbox::class,
'formnumber' => View\Helper\FormNumber::class,
'form_number' => View\Helper\FormNumber::class,
'formNumber' => View\Helper\FormNumber::class,
'FormNumber' => View\Helper\FormNumber::class,
'formpassword' => View\Helper\FormPassword::class,
'form_password' => View\Helper\FormPassword::class,
'formPassword' => View\Helper\FormPassword::class,
'FormPassword' => View\Helper\FormPassword::class,
'formradio' => View\Helper\FormRadio::class,
'form_radio' => View\Helper\FormRadio::class,
'formRadio' => View\Helper\FormRadio::class,
'FormRadio' => View\Helper\FormRadio::class,
'formrange' => View\Helper\FormRange::class,
'form_range' => View\Helper\FormRange::class,
'formRange' => View\Helper\FormRange::class,
'FormRange' => View\Helper\FormRange::class,
'formreset' => View\Helper\FormReset::class,
'form_reset' => View\Helper\FormReset::class,
'formReset' => View\Helper\FormReset::class,
'FormReset' => View\Helper\FormReset::class,
'formrow' => View\Helper\FormRow::class,
'form_row' => View\Helper\FormRow::class,
'formRow' => View\Helper\FormRow::class,
'FormRow' => View\Helper\FormRow::class,
'formsearch' => View\Helper\FormSearch::class,
'form_search' => View\Helper\FormSearch::class,
'formSearch' => View\Helper\FormSearch::class,
'FormSearch' => View\Helper\FormSearch::class,
'formselect' => View\Helper\FormSelect::class,
'form_select' => View\Helper\FormSelect::class,
'formSelect' => View\Helper\FormSelect::class,
'FormSelect' => View\Helper\FormSelect::class,
'formsubmit' => View\Helper\FormSubmit::class,
'form_submit' => View\Helper\FormSubmit::class,
'formSubmit' => View\Helper\FormSubmit::class,
'FormSubmit' => View\Helper\FormSubmit::class,
'formtel' => View\Helper\FormTel::class,
'form_tel' => View\Helper\FormTel::class,
'formTel' => View\Helper\FormTel::class,
'FormTel' => View\Helper\FormTel::class,
'formtext' => View\Helper\FormText::class,
'form_text' => View\Helper\FormText::class,
'formText' => View\Helper\FormText::class,
'FormText' => View\Helper\FormText::class,
'formtextarea' => View\Helper\FormTextarea::class,
'form_text_area' => View\Helper\FormTextarea::class,
'formTextarea' => View\Helper\FormTextarea::class,
'formTextArea' => View\Helper\FormTextarea::class,
'FormTextArea' => View\Helper\FormTextarea::class,
'formtime' => View\Helper\FormTime::class,
'form_time' => View\Helper\FormTime::class,
'formTime' => View\Helper\FormTime::class,
'FormTime' => View\Helper\FormTime::class,
'formurl' => View\Helper\FormUrl::class,
'form_url' => View\Helper\FormUrl::class,
'formUrl' => View\Helper\FormUrl::class,
'FormUrl' => View\Helper\FormUrl::class,
'formweek' => View\Helper\FormWeek::class,
'form_week' => View\Helper\FormWeek::class,
'formWeek' => View\Helper\FormWeek::class,
'FormWeek' => View\Helper\FormWeek::class,
],
'factories' => [
View\Helper\Captcha\Dumb::class => InvokableFactory::class,
View\Helper\Captcha\Figlet::class => InvokableFactory::class,
View\Helper\Captcha\Image::class => InvokableFactory::class,
View\Helper\Captcha\ReCaptcha::class => InvokableFactory::class,
View\Helper\File\FormFileApcProgress::class => InvokableFactory::class,
View\Helper\File\FormFileSessionProgress::class => InvokableFactory::class,
View\Helper\File\FormFileUploadProgress::class => InvokableFactory::class,
View\Helper\Form::class => InvokableFactory::class,
View\Helper\FormButton::class => InvokableFactory::class,
View\Helper\FormCaptcha::class => InvokableFactory::class,
View\Helper\FormCheckbox::class => InvokableFactory::class,
View\Helper\FormCollection::class => InvokableFactory::class,
View\Helper\FormColor::class => InvokableFactory::class,
View\Helper\FormDate::class => InvokableFactory::class,
View\Helper\FormDateSelect::class => InvokableFactory::class,
View\Helper\FormDateTime::class => InvokableFactory::class,
View\Helper\FormDateTimeLocal::class => InvokableFactory::class,
View\Helper\FormDateTimeSelect::class => InvokableFactory::class,
View\Helper\FormElement::class => InvokableFactory::class,
View\Helper\FormElementErrors::class => InvokableFactory::class,
View\Helper\FormEmail::class => InvokableFactory::class,
View\Helper\FormFile::class => InvokableFactory::class,
View\Helper\FormHidden::class => InvokableFactory::class,
View\Helper\FormImage::class => InvokableFactory::class,
View\Helper\FormInput::class => InvokableFactory::class,
View\Helper\FormLabel::class => InvokableFactory::class,
View\Helper\FormMonth::class => InvokableFactory::class,
View\Helper\FormMonthSelect::class => InvokableFactory::class,
View\Helper\FormMultiCheckbox::class => InvokableFactory::class,
View\Helper\FormNumber::class => InvokableFactory::class,
View\Helper\FormPassword::class => InvokableFactory::class,
View\Helper\FormRadio::class => InvokableFactory::class,
View\Helper\FormRange::class => InvokableFactory::class,
View\Helper\FormReset::class => InvokableFactory::class,
View\Helper\FormRow::class => InvokableFactory::class,
View\Helper\FormSearch::class => InvokableFactory::class,
View\Helper\FormSelect::class => InvokableFactory::class,
View\Helper\FormSubmit::class => InvokableFactory::class,
View\Helper\FormTel::class => InvokableFactory::class,
View\Helper\FormText::class => InvokableFactory::class,
View\Helper\FormTextarea::class => InvokableFactory::class,
View\Helper\FormTime::class => InvokableFactory::class,
View\Helper\FormUrl::class => InvokableFactory::class,
View\Helper\FormWeek::class => InvokableFactory::class,
],
];
}
}
================================================
FILE: src/Zend/Form/src/Element/Button.php
================================================
'button',
];
}
================================================
FILE: src/Zend/Form/src/Element/Captcha.php
================================================
options['captcha'])) {
$this->setCaptcha($this->options['captcha']);
}
return $this;
}
/**
* Set captcha
*
* @param array|ZendCaptcha\AdapterInterface $captcha
* @throws Exception\InvalidArgumentException
* @return Captcha
*/
public function setCaptcha($captcha)
{
if (is_array($captcha) || $captcha instanceof Traversable) {
$captcha = ZendCaptcha\Factory::factory($captcha);
} elseif (! $captcha instanceof ZendCaptcha\AdapterInterface) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects either a Zend\Captcha\AdapterInterface or specification to pass to Zend\Captcha\Factory; '
. 'received "%s"',
__METHOD__,
(is_object($captcha) ? get_class($captcha) : gettype($captcha))
));
}
$this->captcha = $captcha;
return $this;
}
/**
* Retrieve captcha (if any)
*
* @return null|ZendCaptcha\AdapterInterface
*/
public function getCaptcha()
{
return $this->captcha;
}
/**
* Provide default input rules for this element
*
* Attaches the captcha as a validator.
*
* @return array
*/
public function getInputSpecification()
{
$spec = [
'name' => $this->getName(),
'required' => true,
'filters' => [
['name' => 'Zend\Filter\StringTrim'],
],
];
// Test that we have a captcha before adding it to the spec
$captcha = $this->getCaptcha();
if ($captcha instanceof ZendCaptcha\AdapterInterface) {
$spec['validators'] = [$captcha];
}
return $spec;
}
}
================================================
FILE: src/Zend/Form/src/Element/Checkbox.php
================================================
'checkbox'
];
/**
* @var \Zend\Validator\ValidatorInterface
*/
protected $validator;
/**
* @var bool
*/
protected $useHiddenElement = true;
/**
* @var string
*/
protected $uncheckedValue = '0';
/**
* @var string
*/
protected $checkedValue = '1';
/**
* Accepted options for MultiCheckbox:
* - use_hidden_element: do we render hidden element?
* - unchecked_value: value for checkbox when unchecked
* - checked_value: value for checkbox when checked
*
* @param array|Traversable $options
* @return Checkbox
*/
public function setOptions($options)
{
parent::setOptions($options);
if (isset($options['use_hidden_element'])) {
$this->setUseHiddenElement($options['use_hidden_element']);
}
if (isset($options['unchecked_value'])) {
$this->setUncheckedValue($options['unchecked_value']);
}
if (isset($options['checked_value'])) {
$this->setCheckedValue($options['checked_value']);
}
return $this;
}
/**
* Do we render hidden element?
*
* @param bool $useHiddenElement
* @return Checkbox
*/
public function setUseHiddenElement($useHiddenElement)
{
$this->useHiddenElement = (bool) $useHiddenElement;
return $this;
}
/**
* Do we render hidden element?
*
* @return bool
*/
public function useHiddenElement()
{
return $this->useHiddenElement;
}
/**
* Set the value to use when checkbox is unchecked
*
* @param $uncheckedValue
* @return Checkbox
*/
public function setUncheckedValue($uncheckedValue)
{
$this->uncheckedValue = $uncheckedValue;
return $this;
}
/**
* Get the value to use when checkbox is unchecked
*
* @return string
*/
public function getUncheckedValue()
{
return $this->uncheckedValue;
}
/**
* Set the value to use when checkbox is checked
*
* @param $checkedValue
* @return Checkbox
*/
public function setCheckedValue($checkedValue)
{
$this->checkedValue = $checkedValue;
return $this;
}
/**
* Get the value to use when checkbox is checked
*
* @return string
*/
public function getCheckedValue()
{
return $this->checkedValue;
}
/**
* Get validator
*
* @return \Zend\Validator\ValidatorInterface
*/
protected function getValidator()
{
if (null === $this->validator) {
$this->validator = new InArrayValidator([
'haystack' => [$this->checkedValue, $this->uncheckedValue],
'strict' => false
]);
}
return $this->validator;
}
/**
* Provide default input rules for this element
*
* Attaches the captcha as a validator.
*
* @return array
*/
public function getInputSpecification()
{
$spec = [
'name' => $this->getName(),
'required' => true,
];
if ($validator = $this->getValidator()) {
$spec['validators'] = [
$validator,
];
}
return $spec;
}
/**
* Checks if this checkbox is checked.
*
* @return bool
*/
public function isChecked()
{
return $this->value === $this->getCheckedValue();
}
/**
* Checks or unchecks the checkbox.
*
* @param bool $value The flag to set.
* @return Checkbox
*/
public function setChecked($value)
{
$this->value = $value ? $this->getCheckedValue() : $this->getUncheckedValue();
return $this;
}
/**
* Checks or unchecks the checkbox.
*
* @param mixed $value A boolean flag or string that is checked against the "checked value".
* @return Element
*/
public function setValue($value)
{
// Cast to strings because POST data comes in string form
$checked = (string) $value === $this->getCheckedValue();
$this->value = $checked ? $this->getCheckedValue() : $this->getUncheckedValue();
return $this;
}
}
================================================
FILE: src/Zend/Form/src/Element/Collection.php
================================================
)
* - template_placeholder: placeholder used in the data template
*
* @param array|Traversable $options
* @return Collection
*/
public function setOptions($options)
{
parent::setOptions($options);
if (isset($options['target_element'])) {
$this->setTargetElement($options['target_element']);
}
if (isset($options['count'])) {
$this->setCount($options['count']);
}
if (isset($options['allow_add'])) {
$this->setAllowAdd($options['allow_add']);
}
if (isset($options['allow_remove'])) {
$this->setAllowRemove($options['allow_remove']);
}
if (isset($options['should_create_template'])) {
$this->setShouldCreateTemplate($options['should_create_template']);
}
if (isset($options['template_placeholder'])) {
$this->setTemplatePlaceholder($options['template_placeholder']);
}
if (isset($options['create_new_objects'])) {
$this->setCreateNewObjects($options['create_new_objects']);
}
return $this;
}
/**
* Checks if the object can be set in this fieldset
*
* @param object $object
* @return bool
*/
public function allowObjectBinding($object)
{
return true;
}
/**
* Set the object used by the hydrator
* In this case the "object" is a collection of objects
*
* @param array|Traversable $object
* @return Fieldset|FieldsetInterface
* @throws Exception\InvalidArgumentException
*/
public function setObject($object)
{
if (! is_array($object) && ! $object instanceof Traversable) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects an array or Traversable object argument; received "%s"',
__METHOD__,
(is_object($object) ? get_class($object) : gettype($object))
));
}
$this->object = $object;
$this->count = max(count($object), $this->count);
return $this;
}
/**
* Populate values
*
* @param array|Traversable $data
* @throws \Zend\Form\Exception\InvalidArgumentException
* @throws \Zend\Form\Exception\DomainException
* @return void
*/
public function populateValues($data)
{
if (! is_array($data) && ! $data instanceof Traversable) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects an array or Traversable set of data; received "%s"',
__METHOD__,
(is_object($data) ? get_class($data) : gettype($data))
));
}
if (! $this->allowRemove && count($data) < $this->count) {
throw new Exception\DomainException(sprintf(
'There are fewer elements than specified in the collection (%s). Either set the allow_remove option '
. 'to true, or re-submit the form.',
get_class($this)
));
}
// Check to see if elements have been replaced or removed
$toRemove = [];
foreach ($this as $name => $elementOrFieldset) {
if (isset($data[$name])) {
continue;
}
if (! $this->allowRemove) {
throw new Exception\DomainException(sprintf(
'Elements have been removed from the collection (%s) but the allow_remove option is not true.',
get_class($this)
));
}
$toRemove[] = $name;
}
foreach ($toRemove as $name) {
$this->remove($name);
}
foreach ($data as $key => $value) {
if ($this->has($key)) {
$elementOrFieldset = $this->get($key);
} else {
$elementOrFieldset = $this->addNewTargetElementInstance($key);
if ($key > $this->lastChildIndex) {
$this->lastChildIndex = $key;
}
}
if ($elementOrFieldset instanceof FieldsetInterface) {
$elementOrFieldset->populateValues($value);
} else {
$elementOrFieldset->setAttribute('value', $value);
}
}
if (! $this->createNewObjects()) {
$this->replaceTemplateObjects();
}
}
/**
* Checks if this fieldset can bind data
*
* @return bool
*/
public function allowValueBinding()
{
return true;
}
/**
* Bind values to the object
*
* @param array $values
* @param array|null $validationGroup
*
* @return array|mixed|void
*/
public function bindValues(array $values = [], ?array $validationGroup = null)
{
$collection = [];
foreach ($values as $name => $value) {
$element = $this->get($name);
if ($element instanceof FieldsetInterface) {
$collection[] = $element->bindValues($value, $validationGroup);
} else {
$collection[] = $value;
}
}
return $collection;
}
/**
* Set the initial count of target element
*
* @param $count
* @return Collection
*/
public function setCount($count)
{
$this->count = $count > 0 ? $count : 0;
return $this;
}
/**
* Get the initial count of target element
*
* @return int
*/
public function getCount()
{
return $this->count;
}
/**
* Set the target element
*
* @param ElementInterface|array|Traversable $elementOrFieldset
* @return Collection
* @throws \Zend\Form\Exception\InvalidArgumentException
*/
public function setTargetElement($elementOrFieldset)
{
if (is_array($elementOrFieldset)
|| ($elementOrFieldset instanceof Traversable && ! $elementOrFieldset instanceof ElementInterface)
) {
$factory = $this->getFormFactory();
$elementOrFieldset = $factory->create($elementOrFieldset);
}
if (! $elementOrFieldset instanceof ElementInterface) {
throw new Exception\InvalidArgumentException(sprintf(
'%s requires that $elementOrFieldset be an object implementing %s; received "%s"',
__METHOD__,
__NAMESPACE__ . '\ElementInterface',
(is_object($elementOrFieldset) ? get_class($elementOrFieldset) : gettype($elementOrFieldset))
));
}
$this->targetElement = $elementOrFieldset;
return $this;
}
/**
* Get target element
*
* @return ElementInterface|null
*/
public function getTargetElement()
{
return $this->targetElement;
}
/**
* Get allow add
*
* @param bool $allowAdd
* @return Collection
*/
public function setAllowAdd($allowAdd)
{
$this->allowAdd = (bool) $allowAdd;
return $this;
}
/**
* Get allow add
*
* @return bool
*/
public function allowAdd()
{
return $this->allowAdd;
}
/**
* @param bool $allowRemove
* @return Collection
*/
public function setAllowRemove($allowRemove)
{
$this->allowRemove = (bool) $allowRemove;
return $this;
}
/**
* @return bool
*/
public function allowRemove()
{
return $this->allowRemove;
}
/**
* If set to true, a template prototype is automatically added to the form
* to ease the creation of dynamic elements through JavaScript
*
* @param bool $shouldCreateTemplate
* @return Collection
*/
public function setShouldCreateTemplate($shouldCreateTemplate)
{
$this->shouldCreateTemplate = (bool) $shouldCreateTemplate;
return $this;
}
/**
* Get if the collection should create a template
*
* @return bool
*/
public function shouldCreateTemplate()
{
return $this->shouldCreateTemplate;
}
/**
* Set the placeholder used in the template generated to help create new elements in JavaScript
*
* @param string $templatePlaceholder
* @return Collection
*/
public function setTemplatePlaceholder($templatePlaceholder)
{
if (is_string($templatePlaceholder)) {
$this->templatePlaceholder = $templatePlaceholder;
}
return $this;
}
/**
* Get the template placeholder
*
* @return string
*/
public function getTemplatePlaceholder()
{
return $this->templatePlaceholder;
}
/**
* @param bool $createNewObjects
* @return Collection
*/
public function setCreateNewObjects($createNewObjects)
{
$this->createNewObjects = (bool) $createNewObjects;
return $this;
}
/**
* @return bool
*/
public function createNewObjects()
{
return $this->createNewObjects;
}
/**
* Get a template element used for rendering purposes only
*
* @return null|ElementInterface|FieldsetInterface
*/
public function getTemplateElement()
{
if ($this->templateElement === null) {
$this->templateElement = $this->createTemplateElement();
}
return $this->templateElement;
}
/**
* Prepare the collection by adding a dummy template element if the user want one
*
* @param FormInterface $form
* @return mixed|void
*/
public function prepareElement(FormInterface $form)
{
if (true === $this->shouldCreateChildrenOnPrepareElement) {
if ($this->targetElement !== null && $this->count > 0) {
while ($this->count > $this->lastChildIndex + 1) {
$this->addNewTargetElementInstance(++$this->lastChildIndex);
}
}
}
// Create a template that will also be prepared
if ($this->shouldCreateTemplate) {
$templateElement = $this->getTemplateElement();
$this->add($templateElement);
}
parent::prepareElement($form);
// The template element has been prepared, but we don't want it to be
// rendered nor validated, so remove it from the list.
if ($this->shouldCreateTemplate) {
$this->remove($this->templatePlaceholder);
}
}
/**
* @return array
* @throws \Zend\Form\Exception\InvalidArgumentException
* @throws \Zend\Stdlib\Exception\InvalidArgumentException
* @throws \Zend\Form\Exception\DomainException
* @throws \Zend\Form\Exception\InvalidElementException
*/
public function extract()
{
if ($this->object instanceof Traversable) {
$this->object = ArrayUtils::iteratorToArray($this->object, false);
}
if (! is_array($this->object)) {
return [];
}
$values = [];
foreach ($this->object as $key => $value) {
// If a hydrator is provided, our work here is done
if ($this->hydrator) {
$values[$key] = $this->hydrator->extract($value);
continue;
}
// If the target element is a fieldset that can accept the provided value
// we should clone it, inject the value and extract the data
if ($this->targetElement instanceof FieldsetInterface) {
if (! $this->targetElement->allowObjectBinding($value)) {
continue;
}
$targetElement = clone $this->targetElement;
$targetElement->setObject($value);
$values[$key] = $targetElement->extract();
if (! $this->createNewObjects() && $this->has($key)) {
$this->get($key)->setObject($value);
}
continue;
}
// If the target element is a non-fieldset element, just use the value
if ($this->targetElement instanceof ElementInterface) {
$values[$key] = $value;
if (! $this->createNewObjects() && $this->has($key)) {
$this->get($key)->setValue($value);
}
continue;
}
}
return $values;
}
/**
* Create a new instance of the target element
*
* @return ElementInterface
*/
protected function createNewTargetElementInstance()
{
return clone $this->targetElement;
}
/**
* Add a new instance of the target element
*
* @param string $name
* @return ElementInterface
* @throws Exception\DomainException
*/
protected function addNewTargetElementInstance($name)
{
$this->shouldCreateChildrenOnPrepareElement = false;
$elementOrFieldset = $this->createNewTargetElementInstance();
$elementOrFieldset->setName($name);
$this->add($elementOrFieldset);
if (! $this->allowAdd && $this->count() > $this->count) {
throw new Exception\DomainException(sprintf(
'There are more elements than specified in the collection (%s). Either set the allow_add option ' .
'to true, or re-submit the form.',
get_class($this)
));
}
return $elementOrFieldset;
}
/**
* Create a dummy template element
*
* @return null|ElementInterface|FieldsetInterface
*/
protected function createTemplateElement()
{
if (! $this->shouldCreateTemplate) {
return;
}
if ($this->templateElement) {
return $this->templateElement;
}
$elementOrFieldset = $this->createNewTargetElementInstance();
$elementOrFieldset->setName($this->templatePlaceholder);
return $elementOrFieldset;
}
/**
* Replaces the default template object of a sub element with the corresponding
* real entity so that all properties are preserved.
*
* @return void
*/
protected function replaceTemplateObjects()
{
$fieldsets = $this->getFieldsets();
if (! count($fieldsets) || ! $this->object) {
return;
}
foreach ($fieldsets as $fieldset) {
$i = $fieldset->getName();
if (isset($this->object[$i])) {
$fieldset->setObject($this->object[$i]);
}
}
}
}
================================================
FILE: src/Zend/Form/src/Element/Color.php
================================================
'color',
];
/**
* @var \Zend\Validator\ValidatorInterface
*/
protected $validator;
/**
* Get validator
*
* @return \Zend\Validator\ValidatorInterface
*/
protected function getValidator()
{
if (null === $this->validator) {
$this->validator = new RegexValidator('/^#[0-9a-fA-F]{6}$/');
}
return $this->validator;
}
/**
* Provide default input rules for this element
*
* Attaches a color validator.
*
* @return array
*/
public function getInputSpecification()
{
return [
'name' => $this->getName(),
'required' => true,
'filters' => [
['name' => 'Zend\Filter\StringTrim'],
['name' => 'Zend\Filter\StringToLower'],
],
'validators' => [
$this->getValidator(),
],
];
}
}
================================================
FILE: src/Zend/Form/src/Element/Csrf.php
================================================
'hidden',
];
/**
* @var array
*/
protected $csrfValidatorOptions = [];
/**
* @var CsrfValidator
*/
protected $csrfValidator;
/**
* Accepted options for Csrf:
* - csrf_options: an array used in the Csrf
*
* @param array|\Traversable $options
* @return Csrf
*/
public function setOptions($options)
{
parent::setOptions($options);
if (isset($options['csrf_options'])) {
$this->setCsrfValidatorOptions($options['csrf_options']);
}
return $this;
}
/**
* @return array
*/
public function getCsrfValidatorOptions()
{
return $this->csrfValidatorOptions;
}
/**
* @param array $options
* @return Csrf
*/
public function setCsrfValidatorOptions(array $options)
{
$this->csrfValidatorOptions = $options;
return $this;
}
/**
* Get CSRF validator
*
* @return CsrfValidator
*/
public function getCsrfValidator()
{
if (null === $this->csrfValidator) {
$csrfOptions = $this->getCsrfValidatorOptions();
$csrfOptions = array_merge($csrfOptions, ['name' => $this->getName()]);
$this->setCsrfValidator(new CsrfValidator($csrfOptions));
}
return $this->csrfValidator;
}
/**
* @param \Zend\Validator\Csrf $validator
* @return Csrf
*/
public function setCsrfValidator(CsrfValidator $validator)
{
$this->csrfValidator = $validator;
return $this;
}
/**
* Retrieve value
*
* Retrieves the hash from the validator
*
* @return string
*/
public function getValue()
{
$validator = $this->getCsrfValidator();
return $validator->getHash();
}
/**
* Override: get attributes
*
* Seeds 'value' attribute with validator hash
*
* @return array
*/
public function getAttributes()
{
$attributes = parent::getAttributes();
$validator = $this->getCsrfValidator();
$attributes['value'] = $validator->getHash();
return $attributes;
}
/**
* Provide default input rules for this element
*
* Attaches the captcha as a validator.
*
* @return array
*/
public function getInputSpecification()
{
return [
'name' => $this->getName(),
'required' => true,
'filters' => [
['name' => 'Zend\Filter\StringTrim'],
],
'validators' => [
$this->getCsrfValidator(),
],
];
}
/**
* Prepare the form element
*/
public function prepareElement(FormInterface $form)
{
$this->getCsrfValidator()->getHash(true);
}
}
================================================
FILE: src/Zend/Form/src/Element/Date.php
================================================
'date',
];
/**
* Date format to use for DateTime values. By default, this is RFC-3339,
* full-date (Y-m-d), which is what HTML5 dictates.
*
* @var string
*/
protected $format = 'Y-m-d';
/**
* Retrieves a DateStep Validator configured for a Date Input type
*
* @return \Zend\Validator\ValidatorInterface
*/
protected function getStepValidator()
{
$format = $this->getFormat();
$stepValue = (isset($this->attributes['step']))
? $this->attributes['step'] : 1; // Days
$baseValue = (isset($this->attributes['min']))
? $this->attributes['min'] : date($format, 0);
return new DateStepValidator([
'format' => $format,
'baseValue' => $baseValue,
'timezone' => new DateTimezone('UTC'),
'step' => new DateInterval("P{$stepValue}D"),
]);
}
}
================================================
FILE: src/Zend/Form/src/Element/DateSelect.php
================================================
dayElement = new Select('day');
parent::__construct($name, $options);
}
/**
* Accepted options for DateSelect (plus the ones from MonthSelect) :
* - day_attributes: HTML attributes to be rendered with the day element
*
* @param array|\Traversable $options
* @return self
*/
public function setOptions($options)
{
parent::setOptions($options);
if (isset($options['day_attributes'])) {
$this->setDayAttributes($options['day_attributes']);
}
return $this;
}
/**
* @return Select
*/
public function getDayElement()
{
return $this->dayElement;
}
/**
* Get both the year and month elements
*
* @return array
*/
public function getElements()
{
return array_merge([$this->dayElement], parent::getElements());
}
/**
* Set the day attributes
*
* @param array $dayAttributes
* @return self
*/
public function setDayAttributes(array $dayAttributes)
{
$this->dayElement->setAttributes($dayAttributes);
return $this;
}
/**
* Get the day attributes
*
* @return array
*/
public function getDayAttributes()
{
return $this->dayElement->getAttributes();
}
/**
* @param string|array|\ArrayAccess|PhpDateTime $value
* @throws \Zend\Form\Exception\InvalidArgumentException
* @return self Provides a fluent interface
*/
public function setValue($value)
{
if (is_string($value)) {
try {
$value = new PhpDateTime($value);
} catch (Exception) {
throw new InvalidArgumentException('Value should be a parsable string or an instance of DateTime');
}
}
if ($value instanceof PhpDateTime) {
$value = [
'year' => $value->format('Y'),
'month' => $value->format('m'),
'day' => $value->format('d'),
];
}
$this->yearElement->setValue($value['year']);
$this->monthElement->setValue($value['month']);
$this->dayElement->setValue($value['day']);
return $this;
}
/**
* @return String
*/
public function getValue()
{
return sprintf(
'%s-%s-%s',
$this->getYearElement()->getValue(),
$this->getMonthElement()->getValue(),
$this->getDayElement()->getValue()
);
}
/**
* Prepare the form element (mostly used for rendering purposes)
*
* @param FormInterface $form
* @return mixed
*/
public function prepareElement(FormInterface $form)
{
parent::prepareElement($form);
$name = $this->getName();
$this->dayElement->setName($name . '[day]');
}
/**
* Get validator
*
* @return ValidatorInterface
*/
protected function getValidator()
{
if (null === $this->validator) {
$this->validator = new DateValidator(['format' => 'Y-m-d']);
}
return $this->validator;
}
/**
* Should return an array specification compatible with
* {@link Zend\InputFilter\Factory::createInput()}.
*
* @return array
*/
public function getInputSpecification()
{
return [
'name' => $this->getName(),
'required' => false,
'filters' => [
['name' => 'DateSelect']
],
'validators' => [
$this->getValidator(),
]
];
}
/**
* Clone the element (this is needed by Collection element, as it needs different copies of the elements)
*/
public function __clone()
{
$this->dayElement = clone $this->dayElement;
$this->monthElement = clone $this->monthElement;
$this->yearElement = clone $this->yearElement;
}
}
================================================
FILE: src/Zend/Form/src/Element/DateTime.php
================================================
'datetime',
];
/**
* A valid format string accepted by date()
*
* @var string
*/
protected $format = self::DATETIME_FORMAT;
/**
* @var array
*/
protected $validators;
/**
* Accepted options for DateTime:
* - format: A \DateTime compatible string
*
* @param array|\Traversable $options
* @return DateTime
*/
public function setOptions($options)
{
parent::setOptions($options);
if (isset($this->options['format'])) {
$this->setFormat($this->options['format']);
}
return $this;
}
/**
* Retrieve the element value
*
* If the value is instance of DateTimeInterface, and $returnFormattedValue
* is true (the default), we return the string representation using the
* currently registered format.
*
* If $returnFormattedValue is false, the original value will be
* returned, regardless of type.
*
* @param bool $returnFormattedValue
* @return mixed
*/
public function getValue($returnFormattedValue = true)
{
$value = parent::getValue();
if (! $value instanceof DateTimeInterface || ! $returnFormattedValue) {
return $value;
}
$format = $this->getFormat();
return $value->format($format);
}
/**
* Set value for format
*
* @param string $format
* @return DateTime
*/
public function setFormat($format)
{
$this->format = (string) $format;
return $this;
}
/**
* Retrieve the DateTime format to use for the value
*
* @return string
*/
public function getFormat()
{
return $this->format;
}
/**
* Get validators
*
* @return array
*/
protected function getValidators()
{
if ($this->validators) {
return $this->validators;
}
$validators = [];
$validators[] = $this->getDateValidator();
if (isset($this->attributes['min'])
&& $this->valueIsValidDateTimeFormat($this->attributes['min'])
) {
$validators[] = new GreaterThanValidator([
'min' => $this->attributes['min'],
'inclusive' => true,
]);
} elseif (isset($this->attributes['min'])
&& ! $this->valueIsValidDateTimeFormat($this->attributes['min'])
) {
throw new InvalidArgumentException(sprintf(
'%1$s expects "min" to conform to %2$s; received "%3$s"',
__METHOD__,
$this->format,
$this->attributes['min']
));
}
if (isset($this->attributes['max'])
&& $this->valueIsValidDateTimeFormat($this->attributes['max'])
) {
$validators[] = new LessThanValidator([
'max' => $this->attributes['max'],
'inclusive' => true,
]);
} elseif (isset($this->attributes['max'])
&& ! $this->valueIsValidDateTimeFormat($this->attributes['max'])
) {
throw new InvalidArgumentException(sprintf(
'%1$s expects "max" to conform to %2$s; received "%3$s"',
__METHOD__,
$this->format,
$this->attributes['max']
));
}
if (! isset($this->attributes['step'])
|| 'any' !== $this->attributes['step']
) {
$validators[] = $this->getStepValidator();
}
$this->validators = $validators;
return $this->validators;
}
/**
* Retrieves a Date Validator configured for a DateTime Input type
*
* @return DateValidator
*/
protected function getDateValidator()
{
return new DateValidator(['format' => $this->format]);
}
/**
* Retrieves a DateStep Validator configured for a DateTime Input type
*
* @return DateStepValidator
*/
protected function getStepValidator()
{
$format = $this->getFormat();
$stepValue = (isset($this->attributes['step']))
? $this->attributes['step'] : 1; // Minutes
$baseValue = (isset($this->attributes['min']))
? $this->attributes['min'] : date($format, 0);
return new DateStepValidator([
'format' => $format,
'baseValue' => $baseValue,
'step' => new DateInterval("PT{$stepValue}M"),
]);
}
/**
* Provide default input rules for this element
*
* Attaches default validators for the datetime input.
*
* @return array
*/
public function getInputSpecification()
{
return [
'name' => $this->getName(),
'required' => true,
'filters' => [
['name' => 'Zend\Filter\StringTrim'],
],
'validators' => $this->getValidators(),
];
}
/**
* Indicate whether or not a value represents a valid DateTime format.
*
* @param string $value
* @return bool
*/
private function valueIsValidDateTimeFormat($value)
{
return PhpDateTime::createFromFormat(
$this->format,
$value
) instanceof DateTimeInterface;
}
}
================================================
FILE: src/Zend/Form/src/Element/DateTimeLocal.php
================================================
'datetime-local',
];
/**
* {@inheritDoc}
*/
protected $format = self::DATETIME_LOCAL_FORMAT;
/**
* Retrieves a DateStepValidator configured for a Date Input type
*
* @return \Zend\Validator\ValidatorInterface
*/
protected function getStepValidator()
{
$stepValue = (isset($this->attributes['step']))
? $this->attributes['step'] : 1; // Minutes
$baseValue = (isset($this->attributes['min']))
? $this->attributes['min'] : '1970-01-01T00:00';
return new DateStepValidator([
'format' => $this->format,
'baseValue' => $baseValue,
'step' => new \DateInterval("PT{$stepValue}M"),
]);
}
}
================================================
FILE: src/Zend/Form/src/Element/DateTimeSelect.php
================================================
hourElement = new Select('hour');
$this->minuteElement = new Select('minute');
$this->secondElement = new Select('second');
}
/**
* Set options for DateTimeSelect element.
*
* Accepted options for DateTimeSelect (plus the ones from DateSelect):
*
* - hour_attributes: HTML attributes to be rendered with the hour element
* - minute_attributes: HTML attributes to be rendered with the minute element
* - second_attributes: HTML attributes to be rendered with the second element
* - should_show_seconds: if set to true, the seconds select is shown
*
* @param array|Traversable $options
* @return self
*/
public function setOptions($options)
{
parent::setOptions($options);
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
}
if (isset($options['hour_attributes'])) {
$this->setHourAttributes($options['hour_attributes']);
}
if (isset($options['minute_attributes'])) {
$this->setMinuteAttributes($options['minute_attributes']);
}
if (isset($options['second_attributes'])) {
$this->setSecondAttributes($options['second_attributes']);
}
if (isset($options['should_show_seconds'])) {
$this->setShouldShowSeconds($options['should_show_seconds']);
}
return $this;
}
/**
* @return Select
*/
public function getHourElement()
{
return $this->hourElement;
}
/**
* @return Select
*/
public function getMinuteElement()
{
return $this->minuteElement;
}
/**
* @return Select
*/
public function getSecondElement()
{
return $this->secondElement;
}
/**
* Set the hour attributes
*
* @param array $hourAttributes
* @return self
*/
public function setHourAttributes(array $hourAttributes)
{
$this->hourElement->setAttributes($hourAttributes);
return $this;
}
/**
* Get the hour attributes
*
* @return array
*/
public function getHourAttributes()
{
return $this->hourElement->getAttributes();
}
/**
* Set the minute attributes
*
* @param array $minuteAttributes
* @return self
*/
public function setMinuteAttributes(array $minuteAttributes)
{
$this->minuteElement->setAttributes($minuteAttributes);
return $this;
}
/**
* Get the minute attributes
*
* @return array
*/
public function getMinuteAttributes()
{
return $this->minuteElement->getAttributes();
}
/**
* Set the second attributes
*
* @param array $secondAttributes
* @return self
*/
public function setSecondAttributes(array $secondAttributes)
{
$this->secondElement->setAttributes($secondAttributes);
return $this;
}
/**
* Get the second attributes
*
* @return array
*/
public function getSecondAttributes()
{
return $this->secondElement->getAttributes();
}
/**
* If set to true, this indicate that the second select is shown. If set to true, the seconds will be
* assumed to always be 00
*
* @param bool $shouldShowSeconds
* @return self
*/
public function setShouldShowSeconds($shouldShowSeconds)
{
$this->shouldShowSeconds = (bool) $shouldShowSeconds;
return $this;
}
/**
* @return bool
*/
public function shouldShowSeconds()
{
return $this->shouldShowSeconds;
}
/**
* @param mixed $value
* @return self
* @throws InvalidArgumentException
*/
public function setValue($value)
{
if (is_string($value)) {
try {
$value = new PhpDateTime($value);
} catch (Exception) {
throw new InvalidArgumentException('Value should be a parsable string or an instance of \DateTime');
}
}
if (null === $value) {
$value = new PhpDateTime();
}
if ($value instanceof PhpDateTime) {
$value = [
'year' => $value->format('Y'),
'month' => $value->format('m'),
'day' => $value->format('d'),
'hour' => $value->format('H'),
'minute' => $value->format('i'),
'second' => $value->format('s')
];
}
if (! isset($value['second'])) {
$value['second'] = '00';
}
$this->yearElement->setValue($value['year']);
$this->monthElement->setValue($value['month']);
$this->dayElement->setValue($value['day']);
$this->hourElement->setValue($value['hour']);
$this->minuteElement->setValue($value['minute']);
$this->secondElement->setValue($value['second']);
return $this;
}
/**
* @return string
*/
public function getValue()
{
return sprintf(
'%s-%s-%s %s:%s:%s',
$this->getYearElement()->getValue(),
$this->getMonthElement()->getValue(),
$this->getDayElement()->getValue(),
$this->getHourElement()->getValue(),
$this->getMinuteElement()->getValue(),
$this->getSecondElement()->getValue()
);
}
/**
* Prepare the form element (mostly used for rendering purposes)
*
* @param FormInterface $form
* @return void
*/
public function prepareElement(FormInterface $form)
{
parent::prepareElement($form);
$name = $this->getName();
$this->hourElement->setName($name . '[hour]');
$this->minuteElement->setName($name . '[minute]');
$this->secondElement->setName($name . '[second]');
}
/**
* Get validator
*
* @return ValidatorInterface
*/
protected function getValidator()
{
if (null === $this->validator) {
$this->validator = new DateValidator(['format' => 'Y-m-d H:i:s']);
}
return $this->validator;
}
/**
* Should return an array specification compatible with
* {@link Zend\InputFilter\Factory::createInput()}.
*
* @return array
*/
public function getInputSpecification()
{
return [
'name' => $this->getName(),
'required' => false,
'filters' => [
['name' => 'DateTimeSelect']
],
'validators' => [
$this->getValidator(),
],
];
}
/**
* Clone the element (this is needed by Collection element, as it needs different copies of the elements)
*/
public function __clone()
{
$this->dayElement = clone $this->dayElement;
$this->monthElement = clone $this->monthElement;
$this->yearElement = clone $this->yearElement;
$this->hourElement = clone $this->hourElement;
$this->minuteElement = clone $this->minuteElement;
$this->secondElement = clone $this->secondElement;
}
}
================================================
FILE: src/Zend/Form/src/Element/Email.php
================================================
'email',
];
/**
* @var ValidatorInterface
*/
protected $validator;
/**
* @var ValidatorInterface
*/
protected $emailValidator;
/**
* Get primary validator
*
* @return ValidatorInterface
*/
public function getValidator()
{
if (null === $this->validator) {
$emailValidator = $this->getEmailValidator();
$multiple = (isset($this->attributes['multiple']))
? $this->attributes['multiple'] : null;
if (true === $multiple || 'multiple' === $multiple) {
$this->validator = new ExplodeValidator([
'validator' => $emailValidator,
]);
} else {
$this->validator = $emailValidator;
}
}
return $this->validator;
}
/**
* Sets the primary validator to use for this element
*
* @param ValidatorInterface $validator
* @return Email
*/
public function setValidator(ValidatorInterface $validator)
{
$this->validator = $validator;
return $this;
}
/**
* Get the email validator to use for multiple or single
* email addresses.
*
* Note from the HTML5 Specs regarding the regex:
*
* "This requirement is a *willful* violation of RFC 5322, which
* defines a syntax for e-mail addresses that is simultaneously
* too strict (before the "@" character), too vague
* (after the "@" character), and too lax (allowing comments,
* whitespace characters, and quoted strings in manners
* unfamiliar to most users) to be of practical use here."
*
* The default Regex validator is in use to match that of the
* browser validation, but you are free to set a different
* (more strict) email validator such as Zend\Validator\Email
* if you wish.
*
* @return ValidatorInterface
*/
public function getEmailValidator()
{
if (null === $this->emailValidator) {
$this->emailValidator = new RegexValidator(
'/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/'
);
}
return $this->emailValidator;
}
/**
* Sets the email validator to use for multiple or single
* email addresses.
*
* @param ValidatorInterface $validator
* @return Email
*/
public function setEmailValidator(ValidatorInterface $validator)
{
$this->emailValidator = $validator;
return $this;
}
/**
* Provide default input rules for this element
*
* Attaches an email validator.
*
* @return array
*/
public function getInputSpecification()
{
return [
'name' => $this->getName(),
'required' => true,
'filters' => [
['name' => 'Zend\Filter\StringTrim'],
],
'validators' => [
$this->getValidator(),
],
];
}
}
================================================
FILE: src/Zend/Form/src/Element/File.php
================================================
'file',
];
/**
* Prepare the form element (mostly used for rendering purposes)
*
* @param FormInterface $form
* @return mixed
*/
public function prepareElement(FormInterface $form)
{
// Ensure the form is using correct enctype
$form->setAttribute('enctype', 'multipart/form-data');
}
/**
* Should return an array specification compatible with
* {@link Zend\InputFilter\Factory::createInput()}.
*
* @return array
*/
public function getInputSpecification()
{
return [
'type' => 'Zend\InputFilter\FileInput',
'name' => $this->getName(),
'required' => false,
];
}
}
================================================
FILE: src/Zend/Form/src/Element/Hidden.php
================================================
'hidden',
];
}
================================================
FILE: src/Zend/Form/src/Element/Image.php
================================================
'image',
];
}
================================================
FILE: src/Zend/Form/src/Element/Month.php
================================================
'month',
];
/**
* Retrieves a Date Validator configured for a Month Input type
*
* @return ValidatorInterface
*/
protected function getDateValidator()
{
return new RegexValidator('/^[0-9]{4}\-(0[1-9]|1[012])$/');
}
/**
* Retrieves a DateStep Validator configured for a Month Input type
*
* @return ValidatorInterface
*/
protected function getStepValidator()
{
$stepValue = (isset($this->attributes['step']))
? $this->attributes['step'] : 1; // Months
$baseValue = (isset($this->attributes['min']))
? $this->attributes['min'] : '1970-01';
return new DateStepValidator([
'format' => "Y-m",
'baseValue' => $baseValue,
'step' => new \DateInterval("P{$stepValue}M"),
]);
}
}
================================================
FILE: src/Zend/Form/src/Element/MonthSelect.php
================================================
elements, according to the
* specified locale
*
* @var bool
*/
protected $renderDelimiters = true;
/**
* @var ValidatorInterface
*/
protected $validator;
/**
* Constructor. Add two selects elements
*
* @param null|int|string $name Optional name for the element
* @param array $options Optional options for the element
*/
public function __construct($name = null, $options = [])
{
$this->minYear = date('Y') - 100;
$this->maxYear = date('Y');
$this->monthElement = new Select('month');
$this->yearElement = new Select('year');
parent::__construct($name, $options);
}
/**
* Set element options.
*
* Accepted options for MonthSelect:
*
* - month_attributes: HTML attributes to be rendered with the month element
* - year_attributes: HTML attributes to be rendered with the month element
* - min_year: min year to use in the year select
* - max_year: max year to use in the year select
*
* @param array|Traversable $options
* @return self
*/
public function setOptions($options)
{
parent::setOptions($options);
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
}
if (isset($options['month_attributes'])) {
$this->setMonthAttributes($options['month_attributes']);
}
if (isset($options['year_attributes'])) {
$this->setYearAttributes($options['year_attributes']);
}
if (isset($options['min_year'])) {
$this->setMinYear($options['min_year']);
}
if (isset($options['max_year'])) {
$this->setMaxYear($options['max_year']);
}
if (isset($options['create_empty_option'])) {
$this->setShouldCreateEmptyOption($options['create_empty_option']);
}
if (isset($options['render_delimiters'])) {
$this->setShouldRenderDelimiters($options['render_delimiters']);
}
return $this;
}
/**
* @return Select
*/
public function getMonthElement()
{
return $this->monthElement;
}
/**
* @return Select
*/
public function getYearElement()
{
return $this->yearElement;
}
/**
* Get both the year and month elements
*
* @return array
*/
public function getElements()
{
return [$this->monthElement, $this->yearElement];
}
/**
* Set the month attributes
*
* @param array $monthAttributes
* @return self
*/
public function setMonthAttributes(array $monthAttributes)
{
$this->monthElement->setAttributes($monthAttributes);
return $this;
}
/**
* Get the month attributes
*
* @return array
*/
public function getMonthAttributes()
{
return $this->monthElement->getAttributes();
}
/**
* Set the year attributes
*
* @param array $yearAttributes
* @return self
*/
public function setYearAttributes(array $yearAttributes)
{
$this->yearElement->setAttributes($yearAttributes);
return $this;
}
/**
* Get the year attributes
*
* @return array
*/
public function getYearAttributes()
{
return $this->yearElement->getAttributes();
}
/**
* @param int $minYear
* @return self
*/
public function setMinYear($minYear)
{
$this->minYear = $minYear;
return $this;
}
/**
* @return int
*/
public function getMinYear()
{
return $this->minYear;
}
/**
* @param int $maxYear
* @return self
*/
public function setMaxYear($maxYear)
{
$this->maxYear = $maxYear;
return $this;
}
/**
* @return int
*/
public function getMaxYear()
{
return $this->maxYear;
}
/**
* @param bool $createEmptyOption
* @return self
*/
public function setShouldCreateEmptyOption($createEmptyOption)
{
$this->createEmptyOption = (bool) $createEmptyOption;
return $this;
}
/**
* @return bool
*/
public function shouldCreateEmptyOption()
{
return $this->createEmptyOption;
}
/**
* @param bool $renderDelimiters
* @return self
*/
public function setShouldRenderDelimiters($renderDelimiters)
{
$this->renderDelimiters = (bool) $renderDelimiters;
return $this;
}
/**
* @return bool
*/
public function shouldRenderDelimiters()
{
return $this->renderDelimiters;
}
/**
* @param mixed $value
* @return self
*/
public function setValue($value)
{
if ($value instanceof PhpDateTime) {
$value = [
'year' => $value->format('Y'),
'month' => $value->format('m')
];
}
$this->yearElement->setValue($value['year']);
$this->monthElement->setValue($value['month']);
return $this;
}
/**
* @return string
*/
public function getValue()
{
return sprintf(
'%s-%s',
$this->getYearElement()->getValue(),
$this->getMonthElement()->getValue()
);
}
/**
* Prepare the form element (mostly used for rendering purposes)
*
* @param FormInterface $form
* @return void
*/
public function prepareElement(FormInterface $form)
{
$name = $this->getName();
$this->monthElement->setName($name . '[month]');
$this->yearElement->setName($name . '[year]');
}
/**
* Get validator
*
* @return ValidatorInterface
*/
protected function getValidator()
{
return new RegexValidator('/^[0-9]{4}\-(0?[1-9]|1[012])$/');
}
/**
* Should return an array specification compatible with
* {@link Zend\InputFilter\Factory::createInput()}.
*
* @return array
*/
public function getInputSpecification()
{
return [
'name' => $this->getName(),
'required' => false,
'filters' => [
['name' => 'MonthSelect'],
],
'validators' => [
$this->getValidator(),
],
];
}
/**
* Clone the element (this is needed by Collection element, as it needs different copies of the elements)
*/
public function __clone()
{
$this->monthElement = clone $this->monthElement;
$this->yearElement = clone $this->yearElement;
}
}
================================================
FILE: src/Zend/Form/src/Element/MultiCheckbox.php
================================================
'multi_checkbox',
];
/**
* @var bool
*/
protected $disableInArrayValidator = false;
/**
* @var bool
*/
protected $useHiddenElement = false;
/**
* @var string
*/
protected $uncheckedValue = '';
/**
* @var array
*/
protected $valueOptions = [];
/**
* @return array
*/
public function getValueOptions()
{
return $this->valueOptions;
}
/**
* @param array $options
* @return MultiCheckbox
*/
public function setValueOptions(array $options)
{
$this->valueOptions = $options;
// Update Explode validator haystack
if ($this->validator instanceof ExplodeValidator) {
$validator = $this->validator->getValidator();
$validator->setHaystack($this->getValueOptionsValues());
}
return $this;
}
/**
* @param string $key
* @return self
*/
public function unsetValueOption($key)
{
if (isset($this->valueOptions[$key])) {
unset($this->valueOptions[$key]);
}
return $this;
}
/**
* Set options for an element. Accepted options are:
* - label: label to associate with the element
* - label_attributes: attributes to use when the label is rendered
* - value_options: list of values and labels for the select options
*
* @param array|\Traversable $options
* @return MultiCheckbox|ElementInterface
* @throws InvalidArgumentException
*/
public function setOptions($options)
{
parent::setOptions($options);
if (isset($this->options['value_options'])) {
$this->setValueOptions($this->options['value_options']);
}
// Alias for 'value_options'
if (isset($this->options['options'])) {
$this->setValueOptions($this->options['options']);
}
if (isset($this->options['disable_inarray_validator'])) {
$this->setDisableInArrayValidator($this->options['disable_inarray_validator']);
}
return $this;
}
/**
* Set a single element attribute
*
* @param string $key
* @param mixed $value
* @return MultiCheckbox|ElementInterface
*/
public function setAttribute($key, $value)
{
// Do not include the options in the list of attributes
// TODO: Deprecate this
if ($key === 'options') {
$this->setValueOptions($value);
return $this;
}
return parent::setAttribute($key, $value);
}
/**
* Set the flag to allow for disabling the automatic addition of an InArray validator.
*
* @param bool $disableOption
* @return Select
*/
public function setDisableInArrayValidator($disableOption)
{
$this->disableInArrayValidator = (bool) $disableOption;
return $this;
}
/**
* Get the disable in array validator flag.
*
* @return bool
*/
public function disableInArrayValidator()
{
return $this->disableInArrayValidator;
}
/**
* Get validator
*
* @return ValidatorInterface
*/
protected function getValidator()
{
if (null === $this->validator && ! $this->disableInArrayValidator()) {
$inArrayValidator = new InArrayValidator([
'haystack' => $this->getValueOptionsValues(),
'strict' => false,
]);
$this->validator = new ExplodeValidator([
'validator' => $inArrayValidator,
'valueDelimiter' => null, // skip explode if only one value
]);
}
return $this->validator;
}
/**
* Get only the values from the options attribute
*
* @return array
*/
protected function getValueOptionsValues()
{
$values = [];
$options = $this->getValueOptions();
foreach ($options as $key => $optionSpec) {
$value = (is_array($optionSpec)) ? $optionSpec['value'] : $key;
$values[] = $value;
}
if ($this->useHiddenElement()) {
$values[] = $this->getUncheckedValue();
}
return $values;
}
/**
* Sets the value that should be selected.
*
* @param mixed $value The value to set.
* @return MultiCheckbox
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
}
================================================
FILE: src/Zend/Form/src/Element/Number.php
================================================
'number',
];
/**
* @var array
*/
protected $validators;
/**
* Get validator
*
* @return \Zend\Validator\ValidatorInterface[]
*/
protected function getValidators()
{
if ($this->validators) {
return $this->validators;
}
$validators = [];
// HTML5 always transmits values in the format "1000.01", without a
// thousand separator. The prior use of the i18n Float validator
// allowed the thousand separator, which resulted in wrong numbers
// when casting to float.
$validators[] = new RegexValidator('(^-?\d*(\.\d+)?$)');
$inclusive = true;
if (isset($this->attributes['inclusive'])) {
$inclusive = $this->attributes['inclusive'];
}
if (isset($this->attributes['min'])) {
$validators[] = new GreaterThanValidator([
'min' => $this->attributes['min'],
'inclusive' => $inclusive
]);
}
if (isset($this->attributes['max'])) {
$validators[] = new LessThanValidator([
'max' => $this->attributes['max'],
'inclusive' => $inclusive
]);
}
if (! isset($this->attributes['step'])
|| 'any' !== $this->attributes['step']
) {
$validators[] = new StepValidator([
'baseValue' => (isset($this->attributes['min'])) ? $this->attributes['min'] : 0,
'step' => (isset($this->attributes['step'])) ? $this->attributes['step'] : 1,
]);
}
$this->validators = $validators;
return $this->validators;
}
/**
* Provide default input rules for this element
*
* Attaches a number validator, as well as a greater than and less than validators
*
* @return array
*/
public function getInputSpecification()
{
return [
'name' => $this->getName(),
'required' => true,
'filters' => [
['name' => 'Zend\Filter\StringTrim']
],
'validators' => $this->getValidators(),
];
}
}
================================================
FILE: src/Zend/Form/src/Element/Password.php
================================================
'password',
];
/**
* Remove the password before rendering if the form fails in order to avoid any security issue
*
* @param FormInterface $form
* @return mixed
*/
public function prepareElement(FormInterface $form)
{
$this->setValue('');
}
}
================================================
FILE: src/Zend/Form/src/Element/Radio.php
================================================
'radio'
];
/**
* Get validator
*
* @return \Zend\Validator\ValidatorInterface
*/
protected function getValidator()
{
if (null === $this->validator && ! $this->disableInArrayValidator()) {
$this->validator = new InArrayValidator([
'haystack' => $this->getValueOptionsValues(),
'strict' => false,
]);
}
return $this->validator;
}
}
================================================
FILE: src/Zend/Form/src/Element/Range.php
================================================
'range',
];
/**
* Get validator
*
* @return \Zend\Validator\ValidatorInterface[]
*/
protected function getValidators()
{
if ($this->validators) {
return $this->validators;
}
$validators = [];
$validators[] = new NumberValidator();
$inclusive = true;
if (! empty($this->attributes['inclusive'])) {
$inclusive = $this->attributes['inclusive'];
}
$validators[] = new GreaterThanValidator([
'min' => (isset($this->attributes['min'])) ? $this->attributes['min'] : 0,
'inclusive' => $inclusive
]);
$validators[] = new LessThanValidator([
'max' => (isset($this->attributes['max'])) ? $this->attributes['max'] : 100,
'inclusive' => $inclusive
]);
if (! isset($this->attributes['step'])
|| 'any' !== $this->attributes['step']
) {
$validators[] = new StepValidator([
'baseValue' => (isset($this->attributes['min'])) ? $this->attributes['min'] : 0,
'step' => (isset($this->attributes['step'])) ? $this->attributes['step'] : 1,
]);
}
$this->validators = $validators;
return $this->validators;
}
}
================================================
FILE: src/Zend/Form/src/Element/Search.php
================================================
'search',
];
}
================================================
FILE: src/Zend/Form/src/Element/Select.php
================================================
'select',
];
/**
* @var \Zend\Validator\ValidatorInterface
*/
protected $validator;
/**
* @var bool
*/
protected $disableInArrayValidator = false;
/**
* Create an empty option (option with label but no value). If set to null, no option is created
*
* @var bool
*/
protected $emptyOption = null;
/**
* @var array
*/
protected $valueOptions = [];
/**
* @var bool
*/
protected $useHiddenElement = false;
/**
* @var string
*/
protected $unselectedValue = '';
/**
* @return array
*/
public function getValueOptions()
{
return $this->valueOptions;
}
/**
* @param array $options
* @return Select
*/
public function setValueOptions(array $options)
{
$this->valueOptions = $options;
// Update InArrayValidator validator haystack
if (null !== $this->validator) {
if ($this->validator instanceof InArrayValidator) {
$validator = $this->validator;
}
if ($this->validator instanceof ExplodeValidator
&& $this->validator->getValidator() instanceof InArrayValidator
) {
$validator = $this->validator->getValidator();
}
if (! empty($validator)) {
$validator->setHaystack($this->getValueOptionsValues());
}
}
return $this;
}
/**
* @param string $key
* @return self
*/
public function unsetValueOption($key)
{
if (isset($this->valueOptions[$key])) {
unset($this->valueOptions[$key]);
}
return $this;
}
/**
* Set options for an element. Accepted options are:
* - label: label to associate with the element
* - label_attributes: attributes to use when the label is rendered
* - value_options: list of values and labels for the select options
* - empty_option: should an empty option be prepended to the options ?
*
* @param array|Traversable $options
* @return Select|ElementInterface
* @throws InvalidArgumentException
*/
public function setOptions($options)
{
parent::setOptions($options);
if (isset($this->options['value_options'])) {
$this->setValueOptions($this->options['value_options']);
}
// Alias for 'value_options'
if (isset($this->options['options'])) {
$this->setValueOptions($this->options['options']);
}
if (isset($this->options['empty_option'])) {
$this->setEmptyOption($this->options['empty_option']);
}
if (isset($this->options['disable_inarray_validator'])) {
$this->setDisableInArrayValidator($this->options['disable_inarray_validator']);
}
if (isset($options['use_hidden_element'])) {
$this->setUseHiddenElement($options['use_hidden_element']);
}
if (isset($options['unselected_value'])) {
$this->setUnselectedValue($options['unselected_value']);
}
return $this;
}
/**
* Set a single element attribute
*
* @param string $key
* @param mixed $value
* @return Select|ElementInterface
*/
public function setAttribute($key, $value)
{
// Do not include the options in the list of attributes
// TODO: Deprecate this
if ($key === 'options') {
$this->setValueOptions($value);
return $this;
}
return parent::setAttribute($key, $value);
}
/**
* Set the flag to allow for disabling the automatic addition of an InArray validator.
*
* @param bool $disableOption
* @return Select
*/
public function setDisableInArrayValidator($disableOption)
{
$this->disableInArrayValidator = (bool) $disableOption;
return $this;
}
/**
* Get the disable in array validator flag.
*
* @return bool
*/
public function disableInArrayValidator()
{
return $this->disableInArrayValidator;
}
/**
* Set the string for an empty option (can be empty string). If set to null, no option will be added
*
* @param string|null $emptyOption
* @return Select
*/
public function setEmptyOption($emptyOption)
{
$this->emptyOption = $emptyOption;
return $this;
}
/**
* Return the string for the empty option (null if none)
*
* @return string|null
*/
public function getEmptyOption()
{
return $this->emptyOption;
}
/**
* Get validator
*
* @return \Zend\Validator\ValidatorInterface
*/
protected function getValidator()
{
if (null === $this->validator && ! $this->disableInArrayValidator()) {
$validator = new InArrayValidator([
'haystack' => $this->getValueOptionsValues(),
'strict' => false
]);
if ($this->isMultiple()) {
$validator = new ExplodeValidator([
'validator' => $validator,
'valueDelimiter' => null, // skip explode if only one value
]);
}
$this->validator = $validator;
}
return $this->validator;
}
/**
* Do we render hidden element?
*
* @param bool $useHiddenElement
* @return Select
*/
public function setUseHiddenElement($useHiddenElement)
{
$this->useHiddenElement = (bool) $useHiddenElement;
return $this;
}
/**
* Do we render hidden element?
*
* @return bool
*/
public function useHiddenElement()
{
return $this->useHiddenElement;
}
/**
* Set the value if the select is not selected
*
* @param string $unselectedValue
* @return Select
*/
public function setUnselectedValue($unselectedValue)
{
$this->unselectedValue = (string) $unselectedValue;
return $this;
}
/**
* Get the value when the select is not selected
*
* @return string
*/
public function getUnselectedValue()
{
return $this->unselectedValue;
}
/**
* Provide default input rules for this element
*
* @return array
*/
public function getInputSpecification()
{
$spec = [
'name' => $this->getName(),
'required' => true,
];
if ($this->useHiddenElement() && $this->isMultiple()) {
$unselectedValue = $this->getUnselectedValue();
$spec['allow_empty'] = true;
$spec['continue_if_empty'] = true;
$spec['filters'] = [[
'name' => 'Callback',
'options' => [
'callback' => function ($value) use ($unselectedValue) {
if ($value === $unselectedValue) {
$value = [];
}
return $value;
}
]
]];
}
if ($validator = $this->getValidator()) {
$spec['validators'] = [
$validator,
];
}
return $spec;
}
/**
* Get only the values from the options attribute
*
* @return array
*/
protected function getValueOptionsValues()
{
$values = [];
$options = $this->getValueOptions();
foreach ($options as $key => $optionSpec) {
if (is_array($optionSpec) && array_key_exists('options', $optionSpec)) {
foreach ($optionSpec['options'] as $nestedKey => $nestedOptionSpec) {
$values[] = $this->getOptionValue($nestedKey, $nestedOptionSpec);
}
continue;
}
$values[] = $this->getOptionValue($key, $optionSpec);
}
return $values;
}
protected function getOptionValue($key, $optionSpec)
{
return is_array($optionSpec) ? $optionSpec['value'] : $key;
}
/**
* Element has the multiple attribute
*
* @return bool
*/
public function isMultiple()
{
return isset($this->attributes['multiple'])
&& ($this->attributes['multiple'] === true || $this->attributes['multiple'] === 'multiple');
}
}
================================================
FILE: src/Zend/Form/src/Element/Submit.php
================================================
'submit',
];
}
================================================
FILE: src/Zend/Form/src/Element/Tel.php
================================================
'tel',
];
/**
* @var ValidatorInterface
*/
protected $validator;
/**
* Get validator
*
* @return ValidatorInterface
*/
protected function getValidator()
{
if (null === $this->validator) {
$this->validator = new RegexValidator("/^[^\r\n]*$/");
}
return $this->validator;
}
/**
* Provide default input rules for this element
*
* @return array
*/
public function getInputSpecification()
{
return [
'name' => $this->getName(),
'required' => true,
'filters' => [
['name' => StringTrim::class],
['name' => StripNewlines::class],
],
'validators' => [
$this->getValidator(),
],
];
}
}
================================================
FILE: src/Zend/Form/src/Element/Text.php
================================================
'text',
];
}
================================================
FILE: src/Zend/Form/src/Element/Textarea.php
================================================
'textarea',
];
}
================================================
FILE: src/Zend/Form/src/Element/Time.php
================================================
'time',
];
/**
* Default date format
* @var string
*/
protected $format = 'H:i:s';
/**
* Retrieves a DateStepValidator configured for a Date Input type
*
* @return \Zend\Validator\ValidatorInterface
*/
protected function getStepValidator()
{
$format = $this->getFormat();
$stepValue = (isset($this->attributes['step']))
? $this->attributes['step'] : 60; // Seconds
$baseValue = (isset($this->attributes['min']))
? $this->attributes['min'] : date($format, 0);
return new DateStepValidator([
'format' => $format,
'baseValue' => $baseValue,
'step' => new DateInterval("PT{$stepValue}S"),
]);
}
}
================================================
FILE: src/Zend/Form/src/Element/Url.php
================================================
'url',
];
/**
* @var \Zend\Validator\ValidatorInterface
*/
protected $validator;
/**
* Get validator
*
* @return \Zend\Validator\ValidatorInterface
*/
public function getValidator()
{
if (null === $this->validator) {
$this->validator = new UriValidator([
'allowAbsolute' => true,
'allowRelative' => false,
]);
}
return $this->validator;
}
/**
* Provide default input rules for this element
*
* Attaches an uri validator.
*
* @return array
*/
public function getInputSpecification()
{
return [
'name' => $this->getName(),
'required' => true,
'filters' => [
['name' => 'Zend\Filter\StringTrim'],
],
'validators' => [
$this->getValidator(),
],
];
}
}
================================================
FILE: src/Zend/Form/src/Element/Week.php
================================================
'week',
];
/**
* Retrieves a Date Validator configured for a Week Input type
*
* @return \Zend\Validator\ValidatorInterface
*/
protected function getDateValidator()
{
return new RegexValidator('/^[0-9]{4}\-W[0-9]{2}$/');
}
/**
* Retrieves a DateStep Validator configured for a Week Input type
*
* @return \Zend\Validator\ValidatorInterface
*/
protected function getStepValidator()
{
$stepValue = (isset($this->attributes['step']))
? $this->attributes['step'] : 1; // Weeks
$baseValue = (isset($this->attributes['min']))
? $this->attributes['min'] : '1970-W01';
return new DateStepValidator([
'format' => 'Y-\WW',
'baseValue' => $baseValue,
'step' => new \DateInterval("P{$stepValue}W"),
]);
}
/**
* @see https://bugs.php.net/bug.php?id=74511
* @return array
*/
protected function getValidators()
{
if ($this->validators) {
return $this->validators;
}
$validators = [];
$validators[] = $this->getDateValidator();
if (isset($this->attributes['min'])) {
$validators[] = new GreaterThanValidator([
'min' => $this->attributes['min'],
'inclusive' => true,
]);
}
if (isset($this->attributes['max'])) {
$validators[] = new LessThanValidator([
'max' => $this->attributes['max'],
'inclusive' => true,
]);
}
if (! isset($this->attributes['step'])
|| 'any' !== $this->attributes['step']
) {
$validators[] = $this->getStepValidator();
}
$this->validators = $validators;
return $this->validators;
}
}
================================================
FILE: src/Zend/Form/src/Element.php
================================================
setName($name);
}
if (! empty($options)) {
$this->setOptions($options);
}
}
/**
* This function is automatically called when creating element with factory. It
* allows to perform various operations (add elements...)
*
* @return void
*/
public function init()
{
}
/**
* Set value for name
*
* @param string $name
* @return Element|ElementInterface
*/
public function setName($name)
{
$this->setAttribute('name', $name);
return $this;
}
/**
* Get value for name
*
* @return string|int
*/
public function getName()
{
return $this->getAttribute('name');
}
/**
* Set options for an element. Accepted options are:
* - label: label to associate with the element
* - label_attributes: attributes to use when the label is rendered
* - label_options: label specific options
*
* @param array|Traversable $options
* @return Element|ElementInterface
* @throws Exception\InvalidArgumentException
*/
public function setOptions($options)
{
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
} elseif (! is_array($options)) {
throw new Exception\InvalidArgumentException(
'The options parameter must be an array or a Traversable'
);
}
if (isset($options['label'])) {
$this->setLabel($options['label']);
}
if (isset($options['label_attributes'])) {
$this->setLabelAttributes($options['label_attributes']);
}
if (isset($options['label_options'])) {
$this->setLabelOptions($options['label_options']);
}
$this->options = $options;
return $this;
}
/**
* Get defined options
*
* @return array
*/
public function getOptions()
{
return $this->options;
}
/**
* Return the specified option
*
* @param string $option
* @return NULL|mixed
*/
public function getOption($option)
{
if (! isset($this->options[$option])) {
return;
}
return $this->options[$option];
}
/**
* Set a single option for an element
*
* @param string $key
* @param mixed $value
* @return self
*/
public function setOption($key, $value)
{
$this->options[$key] = $value;
return $this;
}
/**
* Set a single element attribute
*
* @param string $key
* @param mixed $value
* @return Element|ElementInterface
*/
public function setAttribute($key, $value)
{
// Do not include the value in the list of attributes
if ($key === 'value') {
$this->setValue($value);
return $this;
}
$this->attributes[$key] = $value;
return $this;
}
/**
* Retrieve a single element attribute
*
* @param $key
* @return mixed|null
*/
public function getAttribute($key)
{
if (! isset($this->attributes[$key])) {
return;
}
return $this->attributes[$key];
}
/**
* Remove a single attribute
*
* @param string $key
* @return ElementInterface
*/
public function removeAttribute($key)
{
unset($this->attributes[$key]);
return $this;
}
/**
* Does the element has a specific attribute ?
*
* @param string $key
* @return bool
*/
public function hasAttribute($key)
{
return array_key_exists($key, $this->attributes);
}
/**
* Set many attributes at once
*
* Implementation will decide if this will overwrite or merge.
*
* @param array|Traversable $arrayOrTraversable
* @return Element|ElementInterface
* @throws Exception\InvalidArgumentException
*/
public function setAttributes($arrayOrTraversable)
{
if (! is_array($arrayOrTraversable) && ! $arrayOrTraversable instanceof Traversable) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects an array or Traversable argument; received "%s"',
__METHOD__,
(is_object($arrayOrTraversable) ? get_class($arrayOrTraversable) : gettype($arrayOrTraversable))
));
}
foreach ($arrayOrTraversable as $key => $value) {
$this->setAttribute($key, $value);
}
return $this;
}
/**
* Retrieve all attributes at once
*
* @return array|Traversable
*/
public function getAttributes()
{
return $this->attributes;
}
/**
* Remove many attributes at once
*
* @param array $keys
* @return ElementInterface
*/
public function removeAttributes(array $keys)
{
foreach ($keys as $key) {
unset($this->attributes[$key]);
}
return $this;
}
/**
* Clear all attributes
*
* @return Element|ElementInterface
*/
public function clearAttributes()
{
$this->attributes = [];
return $this;
}
/**
* Set the element value
*
* @param mixed $value
* @return Element
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* Retrieve the element value
*
* @return mixed
*/
public function getValue()
{
return $this->value;
}
/**
* Set the label used for this element
*
* @param $label
* @return Element|ElementInterface
*/
public function setLabel($label)
{
if (is_string($label)) {
$this->label = $label;
}
return $this;
}
/**
* Retrieve the label used for this element
*
* @return null|string
*/
public function getLabel()
{
return $this->label;
}
/**
* Set the attributes to use with the label
*
* @param array $labelAttributes
* @return Element|ElementInterface
*/
public function setLabelAttributes(array $labelAttributes)
{
$this->labelAttributes = $labelAttributes;
return $this;
}
/**
* Get the attributes to use with the label
*
* @return array
*/
public function getLabelAttributes()
{
return $this->labelAttributes;
}
/**
* Set many label options at once
*
* Implementation will decide if this will overwrite or merge.
*
* @param array|Traversable $arrayOrTraversable
* @return Element|ElementInterface
* @throws Exception\InvalidArgumentException
*/
public function setLabelOptions($arrayOrTraversable)
{
if (! is_array($arrayOrTraversable) && ! $arrayOrTraversable instanceof Traversable) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects an array or Traversable argument; received "%s"',
__METHOD__,
(is_object($arrayOrTraversable) ? get_class($arrayOrTraversable) : gettype($arrayOrTraversable))
));
}
foreach ($arrayOrTraversable as $key => $value) {
$this->setLabelOption($key, $value);
}
return $this;
}
/**
* Get label specific options
*
* @return array
*/
public function getLabelOptions()
{
return $this->labelOptions;
}
/**
* Clear all label options
*
* @return Element|ElementInterface
*/
public function clearLabelOptions()
{
$this->labelOptions = [];
return $this;
}
/**
* Remove many attributes at once
*
* @param array $keys
* @return ElementInterface
*/
public function removeLabelOptions(array $keys)
{
foreach ($keys as $key) {
unset($this->labelOptions[$key]);
}
return $this;
}
/**
* Set a single label optionn
*
* @param string $key
* @param mixed $value
* @return Element|ElementInterface
*/
public function setLabelOption($key, $value)
{
$this->labelOptions[$key] = $value;
return $this;
}
/**
* Retrieve a single label option
*
* @param $key
* @return mixed|null
*/
public function getLabelOption($key)
{
if (! isset($this->labelOptions[$key])) {
return;
}
return $this->labelOptions[$key];
}
/**
* Remove a single label option
*
* @param string $key
* @return ElementInterface
*/
public function removeLabelOption($key)
{
unset($this->labelOptions[$key]);
return $this;
}
/**
* Does the element has a specific label option ?
*
* @param string $key
* @return bool
*/
public function hasLabelOption($key)
{
return array_key_exists($key, $this->labelOptions);
}
/**
* Set a list of messages to report when validation fails
*
* @param array|Traversable $messages
* @return Element|ElementInterface
* @throws Exception\InvalidArgumentException
*/
public function setMessages($messages)
{
if (! is_array($messages) && ! $messages instanceof Traversable) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects an array or Traversable object of validation error messages; received "%s"',
__METHOD__,
(is_object($messages) ? get_class($messages) : gettype($messages))
));
}
$this->messages = $messages;
return $this;
}
/**
* Get validation error messages, if any.
*
* Returns a list of validation failure messages, if any.
*
* @return array|Traversable
*/
public function getMessages()
{
return $this->messages;
}
}
================================================
FILE: src/Zend/Form/src/ElementAttributeRemovalInterface.php
================================================
setCreationOptions($creationOptions);
}
/**
* Create an instance of the requested class name.
*
* @param ContainerInterface $container
* @param string $requestedName
* @param array|null $options
* @return object
*/
public function __invoke(ContainerInterface $container, $requestedName, ?array $options = null)
{
if ($options === null) {
$options = [];
}
if (isset($options['name'])) {
$name = $options['name'];
} else {
// 'Zend\Form\Element' -> 'element'
$parts = explode('\\', $requestedName);
$name = strtolower(array_pop($parts));
}
if (isset($options['options'])) {
$options = $options['options'];
}
return new $requestedName($name, $options);
}
/**
* Create an instance of the named service.
*
* First, it checks if `$canonicalName` resolves to a class, and, if so, uses
* that value to proxy to `__invoke()`.
*
* Next, if `$requestedName` is non-empty and resolves to a class, this
* method uses that value to proxy to `__invoke()`.
*
* Finally, if the above each fail, it raises an exception.
*
* The approach above is performed as version 2 has two distinct behaviors
* under which factories are invoked:
*
* - If an alias was used, $canonicalName is the resolved name, and
* $requestedName is the service name requested, in which case $canonicalName
* is likely the qualified class name;
* - Otherwise, $canonicalName is the normalized name, and $requestedName
* is the original service name requested (typically the qualified class name).
*
* @param ServiceLocatorInterface $serviceLocator
* @param null|string $canonicalName
* @param null|string $requestedName
* @return object
* @throws InvalidServiceException
*/
public function createService(ServiceLocatorInterface $serviceLocator, $canonicalName = null, $requestedName = null)
{
if (class_exists($canonicalName)) {
return $this($serviceLocator, $canonicalName, $this->creationOptions);
}
if (is_string($requestedName) && class_exists($requestedName)) {
return $this($serviceLocator, $requestedName, $this->creationOptions);
}
throw new InvalidServiceException(sprintf(
'%s requires that the requested name is provided on invocation; please update your tests or '
. 'consuming container',
__CLASS__
));
}
/**
* {@inheritdoc}
*/
public function setCreationOptions(array $creationOptions)
{
if ($creationOptions instanceof Traversable) {
$creationOptions = iterator_to_array($creationOptions);
}
if (! is_array($creationOptions)) {
throw new InvalidServiceException(sprintf(
'%s cannot use non-array, non-traversable creation options; received %s',
__CLASS__,
(is_object($creationOptions) ? get_class($creationOptions) : gettype($creationOptions))
));
}
$this->creationOptions = $creationOptions;
}
}
================================================
FILE: src/Zend/Form/src/ElementInterface.php
================================================
setFormElementManager($formElementManager);
}
if ($inputFilterFactory) {
$this->setInputFilterFactory($inputFilterFactory);
}
}
/**
* Set input filter factory to use when creating forms
*
* @param InputFilterFactory $inputFilterFactory
* @return Factory
*/
public function setInputFilterFactory(InputFilterFactory $inputFilterFactory)
{
$this->inputFilterFactory = $inputFilterFactory;
return $this;
}
/**
* Get current input filter factory
*
* If none provided, uses an unconfigured instance.
*
* @return InputFilterFactory
*/
public function getInputFilterFactory()
{
if (null === $this->inputFilterFactory) {
$this->setInputFilterFactory(new InputFilterFactory());
}
return $this->inputFilterFactory;
}
/**
* Set the form element manager
*
* @param FormElementManager $formElementManager
* @return Factory
*/
public function setFormElementManager(FormElementManager $formElementManager)
{
$this->formElementManager = $formElementManager;
return $this;
}
/**
* Get form element manager
*
* @return FormElementManager
*/
public function getFormElementManager()
{
if ($this->formElementManager === null) {
$this->setFormElementManager(new FormElementManager(new ServiceManager()));
}
return $this->formElementManager;
}
/**
* Create an element, fieldset, or form
*
* Introspects the 'type' key of the provided $spec, and determines what
* type is being requested; if none is provided, assumes the spec
* represents simply an element.
*
* @param array|Traversable $spec
* @return ElementInterface
* @throws Exception\DomainException
*/
public function create($spec)
{
$spec = $this->validateSpecification($spec, __METHOD__);
$type = isset($spec['type']) ? $spec['type'] : Element::class;
$element = $this->getFormElementManager()->get($type);
if ($element instanceof FormInterface) {
return $this->configureForm($element, $spec);
}
if ($element instanceof FieldsetInterface) {
return $this->configureFieldset($element, $spec);
}
if ($element instanceof ElementInterface) {
return $this->configureElement($element, $spec);
}
throw new Exception\DomainException(sprintf(
'%s expects the $spec["type"] to implement one of %s, %s, or %s; received %s',
__METHOD__,
ElementInterface::class,
FieldsetInterface::class,
FormInterface::class,
$type
));
}
/**
* Create an element
*
* @param array $spec
* @return ElementInterface
*/
public function createElement($spec)
{
if (! isset($spec['type'])) {
$spec['type'] = Element::class;
}
return $this->create($spec);
}
/**
* Create a fieldset
*
* @param array $spec
* @return ElementInterface
*/
public function createFieldset($spec)
{
if (! isset($spec['type'])) {
$spec['type'] = Fieldset::class;
}
return $this->create($spec);
}
/**
* Create a form
*
* @param array $spec
* @return ElementInterface
*/
public function createForm($spec)
{
if (! isset($spec['type'])) {
$spec['type'] = Form::class;
}
return $this->create($spec);
}
/**
* Configure an element based on the provided specification
*
* Specification can contain any of the following:
* - type: the Element class to use; defaults to \Zend\Form\Element
* - name: what name to provide the element, if any
* - options: an array, Traversable, or ArrayAccess object of element options
* - attributes: an array, Traversable, or ArrayAccess object of element
* attributes to assign
*
* @param ElementInterface $element
* @param array|Traversable|ArrayAccess $spec
* @throws Exception\DomainException
* @return ElementInterface
*/
public function configureElement(ElementInterface $element, $spec)
{
$spec = $this->validateSpecification($spec, __METHOD__);
$name = isset($spec['name']) ? $spec['name'] : null;
$options = isset($spec['options']) ? $spec['options'] : null;
$attributes = isset($spec['attributes']) ? $spec['attributes'] : null;
if ($name !== null && $name !== '') {
$element->setName($name);
}
if (is_array($options) || $options instanceof Traversable || $options instanceof ArrayAccess) {
$element->setOptions($options);
}
if (is_array($attributes) || $attributes instanceof Traversable || $attributes instanceof ArrayAccess) {
$element->setAttributes($attributes);
}
return $element;
}
/**
* Configure a fieldset based on the provided specification
*
* Specification can contain any of the following:
* - type: the Fieldset class to use; defaults to \Zend\Form\Fieldset
* - name: what name to provide the fieldset, if any
* - options: an array, Traversable, or ArrayAccess object of element options
* - attributes: an array, Traversable, or ArrayAccess object of element
* attributes to assign
* - elements: an array or Traversable object where each entry is an array
* or ArrayAccess object containing the keys:
* - flags: (optional) array of flags to pass to FieldsetInterface::add()
* - spec: the actual element specification, per {@link configureElement()}
*
* @param FieldsetInterface $fieldset
* @param array|Traversable|ArrayAccess $spec
* @throws Exception\DomainException
* @return FieldsetInterface
*/
public function configureFieldset(FieldsetInterface $fieldset, $spec)
{
$spec = $this->validateSpecification($spec, __METHOD__);
$fieldset = $this->configureElement($fieldset, $spec);
if (isset($spec['object'])) {
$this->prepareAndInjectObject($spec['object'], $fieldset, __METHOD__);
}
if (isset($spec['hydrator'])) {
$this->prepareAndInjectHydrator($spec['hydrator'], $fieldset, __METHOD__);
}
if (isset($spec['elements'])) {
$this->prepareAndInjectElements($spec['elements'], $fieldset, __METHOD__);
}
if (isset($spec['fieldsets'])) {
$this->prepareAndInjectFieldsets($spec['fieldsets'], $fieldset, __METHOD__);
}
$factory = (isset($spec['factory']) ? $spec['factory'] : $this);
$this->prepareAndInjectFactory($factory, $fieldset, __METHOD__);
return $fieldset;
}
/**
* Configure a form based on the provided specification
*
* Specification follows that of {@link configureFieldset()}, and adds the
* following keys:
*
* - input_filter: input filter instance, named input filter class, or
* array specification for the input filter factory
* - hydrator: hydrator instance or named hydrator class
*
* @param FormInterface $form
* @param array|Traversable|ArrayAccess $spec
* @return FormInterface
*/
public function configureForm(FormInterface $form, $spec)
{
$spec = $this->validateSpecification($spec, __METHOD__);
$form = $this->configureFieldset($form, $spec);
if (isset($spec['input_filter'])) {
$this->prepareAndInjectInputFilter($spec['input_filter'], $form, __METHOD__);
}
if (isset($spec['validation_group'])) {
$this->prepareAndInjectValidationGroup($spec['validation_group'], $form, __METHOD__);
}
return $form;
}
/**
* Validate a provided specification
*
* Ensures we have an array, Traversable, or ArrayAccess object, and returns it.
*
* @param array|Traversable|ArrayAccess $spec
* @param string $method Method invoking the validator
* @return array|ArrayAccess
* @throws Exception\InvalidArgumentException for invalid $spec
*/
protected function validateSpecification($spec, $method)
{
if (is_array($spec)) {
return $spec;
}
if ($spec instanceof Traversable) {
$spec = ArrayUtils::iteratorToArray($spec);
return $spec;
}
if (! $spec instanceof ArrayAccess) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects an array, or object implementing Traversable or ArrayAccess; received "%s"',
$method,
(is_object($spec) ? get_class($spec) : gettype($spec))
));
}
return $spec;
}
/**
* Takes a list of element specifications, creates the elements, and injects them into the provided fieldset
*
* @param array|Traversable|ArrayAccess $elements
* @param FieldsetInterface $fieldset
* @param string $method Method invoking this one (for exception messages)
* @return void
*/
protected function prepareAndInjectElements($elements, FieldsetInterface $fieldset, $method)
{
$elements = $this->validateSpecification($elements, $method);
foreach ($elements as $elementSpecification) {
if (null === $elementSpecification) {
continue;
}
$flags = $elementSpecification['flags'] ?? [];
$spec = $elementSpecification['spec'] ?? [];
if (! isset($spec['type'])) {
$spec['type'] = 'Zend\Form\Element';
}
$element = $this->create($spec);
$fieldset->add($element, $flags);
}
}
/**
* Takes a list of fieldset specifications, creates the fieldsets, and injects them into the master fieldset
*
* @param array|Traversable|ArrayAccess $fieldsets
* @param FieldsetInterface $masterFieldset
* @param string $method Method invoking this one (for exception messages)
* @return void
*/
public function prepareAndInjectFieldsets($fieldsets, FieldsetInterface $masterFieldset, $method)
{
$fieldsets = $this->validateSpecification($fieldsets, $method);
foreach ($fieldsets as $fieldsetSpecification) {
$flags = $fieldsetSpecification['flags'] ?? [];
$spec = $fieldsetSpecification['spec'] ?? [];
$fieldset = $this->createFieldset($spec);
$masterFieldset->add($fieldset, $flags);
}
}
/**
* Prepare and inject an object
*
* Takes a string indicating a class name, instantiates the class
* by that name, and injects the class instance as the bound object.
*
* @param string $objectName
* @param FieldsetInterface $fieldset
* @param string $method
* @throws Exception\DomainException
* @return void
*/
protected function prepareAndInjectObject($objectName, FieldsetInterface $fieldset, $method)
{
if (! is_string($objectName)) {
throw new Exception\DomainException(sprintf(
'%s expects string class name; received "%s"',
$method,
(is_object($objectName) ? get_class($objectName) : gettype($objectName))
));
}
if (! class_exists($objectName)) {
throw new Exception\DomainException(sprintf(
'%s expects string class name to be a valid class name; received "%s"',
$method,
$objectName
));
}
$fieldset->setObject(new $objectName);
}
/**
* Prepare and inject a named hydrator
*
* Takes a string indicating a hydrator class name (or a concrete instance), try first to instantiates the class
* by pulling it from service manager, and injects the hydrator instance into the form.
*
* @param string|array|Hydrator\HydratorInterface $hydratorOrName
* @param FieldsetInterface $fieldset
* @param string $method
* @return void
* @throws Exception\DomainException If $hydratorOrName is not a string, does not resolve to a known class, or
* the class does not implement Hydrator\HydratorInterface
*/
protected function prepareAndInjectHydrator($hydratorOrName, FieldsetInterface $fieldset, $method)
{
if ($hydratorOrName instanceof Hydrator\HydratorInterface) {
$fieldset->setHydrator($hydratorOrName);
return;
}
if (is_array($hydratorOrName)) {
if (! isset($hydratorOrName['type'])) {
throw new Exception\DomainException(sprintf(
'%s expects array specification to have a type value',
$method
));
}
$hydratorOptions = (isset($hydratorOrName['options'])) ? $hydratorOrName['options'] : [];
$hydratorOrName = $hydratorOrName['type'];
} else {
$hydratorOptions = [];
}
if (is_string($hydratorOrName)) {
$hydrator = $this->getFormElementManager()->getHydratorFromName($hydratorOrName);
}
if (! isset($hydrator) || ! $hydrator instanceof Hydrator\HydratorInterface) {
throw new Exception\DomainException(sprintf(
'%s expects a valid implementation of Zend\Hydrator\HydratorInterface; received "%s"',
$method,
$hydratorOrName
));
}
if (! empty($hydratorOptions) && $hydrator instanceof Hydrator\HydratorOptionsInterface) {
$hydrator->setOptions($hydratorOptions);
}
$fieldset->setHydrator($hydrator);
}
/**
* Prepare and inject a named factory
*
* Takes a string indicating a factory class name (or a concrete instance), try first to instantiates the class
* by pulling it from service manager, and injects the factory instance into the fieldset.
*
* @param string|array|Factory $factoryOrName
* @param FieldsetInterface $fieldset
* @param string $method
* @return void
* @throws Exception\DomainException If $factoryOrName is not a string, does not resolve to a known class, or
* the class does not extend Form\Factory
*/
protected function prepareAndInjectFactory($factoryOrName, FieldsetInterface $fieldset, $method)
{
if (is_array($factoryOrName)) {
if (! isset($factoryOrName['type'])) {
throw new Exception\DomainException(sprintf(
'%s expects array specification to have a type value',
$method
));
}
$factoryOrName = $factoryOrName['type'];
}
if (is_string($factoryOrName)) {
$factoryOrName = $this->getFormElementManager()->getFactoryFromName($factoryOrName);
}
if (! $factoryOrName instanceof Factory) {
throw new Exception\DomainException(sprintf(
'%s expects a valid extension of Zend\Form\Factory; received "%s"',
$method,
$factoryOrName
));
}
$fieldset->setFormFactory($factoryOrName);
}
/**
* Prepare an input filter instance and inject in the provided form
*
* If the input filter specified is a string, assumes it is a class name,
* and attempts to instantiate it. If the class does not exist, or does
* not extend InputFilterInterface, an exception is raised.
*
* Otherwise, $spec is passed on to the attached InputFilter Factory
* instance in order to create the input filter.
*
* @param string|array|Traversable $spec
* @param FormInterface $form
* @param string $method
* @return void
* @throws Exception\DomainException for unknown InputFilter class or invalid InputFilter instance
*/
protected function prepareAndInjectInputFilter($spec, FormInterface $form, $method)
{
if ($spec instanceof InputFilterInterface) {
$form->setInputFilter($spec);
return;
}
if (is_string($spec)) {
if (! class_exists($spec)) {
throw new Exception\DomainException(sprintf(
'%s expects string input filter names to be valid class names; received "%s"',
$method,
$spec
));
}
$filter = new $spec;
if (! $filter instanceof InputFilterInterface) {
throw new Exception\DomainException(sprintf(
'%s expects a valid implementation of Zend\InputFilter\InputFilterInterface; received "%s"',
$method,
$spec
));
}
$form->setInputFilter($filter);
return;
}
$factory = $this->getInputFilterFactory();
$filter = $factory->createInputFilter($spec);
if (method_exists($filter, 'setFactory')) {
$filter->setFactory($factory);
}
$form->setInputFilter($filter);
}
/**
* Prepare a validation group and inject in the provided form
*
* Takes an array of elements names
*
* @param string|array|Traversable $spec
* @param FormInterface $form
* @param string $method
* @return void
* @throws Exception\DomainException if validation group given is not an array
*/
protected function prepareAndInjectValidationGroup($spec, FormInterface $form, $method)
{
if (! is_array($spec)) {
if (! class_exists($spec)) {
throw new Exception\DomainException(sprintf(
'%s expects an array for validation group; received "%s"',
$method,
$spec
));
}
}
$form->setValidationGroup($spec);
}
/**
* Try to pull hydrator from service manager, or instantiates it from its name
*
* @param string $hydratorName
* @return mixed
* @throws Exception\DomainException
*/
protected function getHydratorFromName($hydratorName)
{
trigger_error(sprintf(
'Usage of %s is deprecated since v3.0.0; please use FormElementManager::getHydratorFromName() instead',
__METHOD__
), E_USER_DEPRECATED);
return $this->getFormElementManager()->getHydratorFromName($hydratorName);
}
/**
* Try to pull factory from service manager, or instantiates it from its name
*
* @param string $factoryName
* @return mixed
* @throws Exception\DomainException
*/
protected function getFactoryFromName($factoryName)
{
trigger_error(sprintf(
'Usage of %s is deprecated since v3.0.0; please use FormElementManager::getFactoryFromName() instead',
__METHOD__
), E_USER_DEPRECATED);
return $this->getFormElementManager()->getFactoryFromName($factoryName);
}
}
================================================
FILE: src/Zend/Form/src/Fieldset.php
================================================
iterator = new PriorityList();
$this->iterator->isLIFO(false);
parent::__construct($name, $options);
}
/**
* Set options for a fieldset. Accepted options are:
* - use_as_base_fieldset: is this fieldset use as the base fieldset?
*
* @param array|Traversable $options
* @return Element|ElementInterface
* @throws Exception\InvalidArgumentException
*/
public function setOptions($options)
{
parent::setOptions($options);
if (isset($options['use_as_base_fieldset'])) {
$this->setUseAsBaseFieldset($options['use_as_base_fieldset']);
}
if (isset($options['allowed_object_binding_class'])) {
$this->setAllowedObjectBindingClass($options['allowed_object_binding_class']);
}
return $this;
}
/**
* Compose a form factory to use when calling add() with a non-element/fieldset
*
* @param Factory $factory
* @return Form
*/
public function setFormFactory(Factory $factory)
{
$this->factory = $factory;
return $this;
}
/**
* Retrieve composed form factory
*
* Lazy-loads one if none present.
*
* @return Factory
*/
public function getFormFactory()
{
if (null === $this->factory) {
$this->setFormFactory(new Factory());
}
return $this->factory;
}
/**
* Add an element or fieldset
*
* $flags could contain metadata such as the alias under which to register
* the element or fieldset, order in which to prioritize it, etc.
*
* @todo Should we detect if the element/fieldset name conflicts?
* @param array|Traversable|ElementInterface $elementOrFieldset
* @param array $flags
* @return Fieldset|FieldsetInterface
* @throws Exception\InvalidArgumentException
*/
public function add($elementOrFieldset, array $flags = [])
{
if (is_array($elementOrFieldset)
|| ($elementOrFieldset instanceof Traversable && ! $elementOrFieldset instanceof ElementInterface)
) {
$factory = $this->getFormFactory();
$elementOrFieldset = $factory->create($elementOrFieldset);
}
if (! $elementOrFieldset instanceof ElementInterface) {
throw new Exception\InvalidArgumentException(sprintf(
'%s requires that $elementOrFieldset be an object implementing %s; received "%s"',
__METHOD__,
__NAMESPACE__ . '\ElementInterface',
(is_object($elementOrFieldset) ? get_class($elementOrFieldset) : gettype($elementOrFieldset))
));
}
$name = $elementOrFieldset->getName();
if ((null === $name || '' === $name)
&& (! array_key_exists('name', $flags) || $flags['name'] === '')
) {
throw new Exception\InvalidArgumentException(sprintf(
'%s: element or fieldset provided is not named, and no name provided in flags',
__METHOD__
));
}
if (array_key_exists('name', $flags) && $flags['name'] !== '') {
$name = $flags['name'];
// Rename the element or fieldset to the specified alias
$elementOrFieldset->setName($name);
}
$order = 0;
if (array_key_exists('priority', $flags)) {
$order = $flags['priority'];
}
$this->iterator->insert($name, $elementOrFieldset, $order);
if ($elementOrFieldset instanceof FieldsetInterface) {
$this->fieldsets[$name] = $elementOrFieldset;
return $this;
}
$this->elements[$name] = $elementOrFieldset;
return $this;
}
/**
* Does the fieldset have an element/fieldset by the given name?
*
* @param string $elementOrFieldset
* @return bool
*/
public function has($elementOrFieldset)
{
return $this->iterator->get($elementOrFieldset) !== null;
}
/**
* Retrieve a named element or fieldset
*
* @param string $elementOrFieldset
* @return ElementInterface|FieldsetInterface
*/
public function get($elementOrFieldset)
{
if (! $this->has($elementOrFieldset)) {
throw new Exception\InvalidElementException(sprintf(
"No element by the name of [%s] found in form",
$elementOrFieldset
));
}
return $this->iterator->get($elementOrFieldset);
}
/**
* Remove a named element or fieldset
*
* @param string $elementOrFieldset
* @return FieldsetInterface
*/
public function remove($elementOrFieldset)
{
if (! $this->has($elementOrFieldset)) {
return $this;
}
$this->iterator->remove($elementOrFieldset);
if (isset($this->fieldsets[$elementOrFieldset])) {
unset($this->fieldsets[$elementOrFieldset]);
return $this;
}
unset($this->elements[$elementOrFieldset]);
return $this;
}
/**
* Set/change the priority of an element or fieldset
*
* @param string $elementOrFieldset
* @param int $priority
* @return FieldsetInterface
*/
public function setPriority($elementOrFieldset, $priority)
{
$this->iterator->setPriority($elementOrFieldset, $priority);
return $this;
}
/**
* Retrieve all attached elements
*
* Storage is an implementation detail of the concrete class.
*
* @return array|Traversable
*/
public function getElements()
{
return $this->elements;
}
/**
* Retrieve all attached fieldsets
*
* Storage is an implementation detail of the concrete class.
*
* @return array|Traversable
*/
public function getFieldsets()
{
return $this->fieldsets;
}
/**
* Set a hash of element names/messages to use when validation fails
*
* @param array|Traversable $messages
* @return Element|ElementInterface|FieldsetInterface
* @throws Exception\InvalidArgumentException
*/
public function setMessages($messages)
{
if (! is_array($messages) && ! $messages instanceof Traversable) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects an array or Traversable object of messages; received "%s"',
__METHOD__,
(is_object($messages) ? get_class($messages) : gettype($messages))
));
}
foreach ($messages as $key => $messageSet) {
if (! $this->has($key)) {
$this->messages[$key] = $messageSet;
continue;
}
$element = $this->get($key);
$element->setMessages($messageSet);
}
return $this;
}
/**
* Get validation error messages, if any
*
* Returns a hash of element names/messages for all elements failing
* validation, or, if $elementName is provided, messages for that element
* only.
*
* @param null|string $elementName
* @return array|Traversable
* @throws Exception\InvalidArgumentException
*/
public function getMessages($elementName = null)
{
if (null === $elementName) {
$messages = $this->messages;
foreach ($this->iterator as $name => $element) {
$messageSet = $element->getMessages();
if (! is_array($messageSet)
&& ! $messageSet instanceof Traversable
|| empty($messageSet)) {
continue;
}
$messages[$name] = $messageSet;
}
return $messages;
}
if (! $this->has($elementName)) {
throw new Exception\InvalidArgumentException(sprintf(
'Invalid element name "%s" provided to %s',
$elementName,
__METHOD__
));
}
$element = $this->get($elementName);
return $element->getMessages();
}
/**
* Ensures state is ready for use. Here, we append the name of the fieldsets to every elements in order to avoid
* name clashes if the same fieldset is used multiple times
*
* @param FormInterface $form
* @return mixed|void
*/
public function prepareElement(FormInterface $form)
{
$name = $this->getName();
foreach ($this->iterator as $elementOrFieldset) {
$elementOrFieldset->setName($name . '[' . $elementOrFieldset->getName() . ']');
// Recursively prepare elements
if ($elementOrFieldset instanceof ElementPrepareAwareInterface) {
$elementOrFieldset->prepareElement($form);
}
}
}
/**
* Recursively populate values of attached elements and fieldsets
*
* @param array|Traversable $data
* @return void
* @throws Exception\InvalidArgumentException
*/
public function populateValues($data)
{
if (! is_array($data) && ! $data instanceof Traversable) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects an array or Traversable set of data; received "%s"',
__METHOD__,
(is_object($data) ? get_class($data) : gettype($data))
));
}
foreach ($this->iterator as $name => $elementOrFieldset) {
$valueExists = array_key_exists($name, $data);
if ($elementOrFieldset instanceof FieldsetInterface) {
if ($valueExists && (is_array($data[$name]) || $data[$name] instanceof Traversable)) {
$elementOrFieldset->populateValues($data[$name]);
continue;
}
if ($elementOrFieldset instanceof Element\Collection) {
if ($valueExists && null !== $data[$name]) {
$elementOrFieldset->populateValues($data[$name]);
continue;
}
/* This ensures that collections with allow_remove don't re-create child
* elements if they all were removed */
$elementOrFieldset->populateValues([]);
continue;
}
}
if ($valueExists) {
$elementOrFieldset->setValue($data[$name]);
}
}
}
/**
* Countable: return count of attached elements/fieldsets
*
* @return int
*/
#[ReturnTypeWillChange] public function count()
{
return $this->iterator->count();
}
/**
* IteratorAggregate: return internal iterator
*
* @return PriorityList
*/
#[ReturnTypeWillChange] public function getIterator()
{
return $this->iterator;
}
/**
* Set the object used by the hydrator
*
* @param object $object
* @return Fieldset|FieldsetInterface
* @throws Exception\InvalidArgumentException
*/
public function setObject($object)
{
if (! is_object($object)) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects an object argument; received "%s"',
__METHOD__,
$object
));
}
$this->object = $object;
return $this;
}
/**
* Get the object used by the hydrator
*
* @return mixed
*/
public function getObject()
{
return $this->object;
}
/**
* Set the class or interface of objects that can be bound to this fieldset.
*
* @param string $allowObjectBindingClass
*/
public function setAllowedObjectBindingClass($allowObjectBindingClass)
{
$this->allowedObjectBindingClass = $allowObjectBindingClass;
}
/**
* Get The class or interface of objects that can be bound to this fieldset.
*
* @return string
*/
public function allowedObjectBindingClass()
{
return $this->allowedObjectBindingClass;
}
/**
* Checks if the object can be set in this fieldset
*
* @param object $object
* @return bool
*/
public function allowObjectBinding($object)
{
$validBindingClass = false;
if (is_object($object) && $this->allowedObjectBindingClass()) {
$objectClass = ltrim($this->allowedObjectBindingClass(), '\\');
$reflection = new ClassReflection($object);
$validBindingClass = (
$reflection->getName() == $objectClass
|| $reflection->isSubclassOf($this->allowedObjectBindingClass())
);
}
return ($validBindingClass || $this->object && $object instanceof $this->object);
}
/**
* Set the hydrator to use when binding an object to the element
*
* @param HydratorInterface $hydrator
* @return FieldsetInterface
*/
public function setHydrator(HydratorInterface $hydrator)
{
$this->hydrator = $hydrator;
return $this;
}
/**
* Get the hydrator used when binding an object to the fieldset
*
* If no hydrator is present and object implements HydratorAwareInterface,
* hydrator will be retrieved from the object.
*
* Will lazy-load Hydrator\ArraySerializable if none is present.
*
* @return HydratorInterface
*/
public function getHydrator()
{
if (! $this->hydrator instanceof HydratorInterface) {
if ($this->object instanceof HydratorAwareInterface) {
$this->setHydrator($this->object->getHydrator());
} else {
$this->setHydrator(
class_exists(Hydrator\ArraySerializableHydrator::class)
? new Hydrator\ArraySerializableHydrator()
: new Hydrator\ArraySerializable()
);
}
}
return $this->hydrator;
}
/**
* Checks if this fieldset can bind data
*
* @return bool
*/
public function allowValueBinding()
{
return is_object($this->object);
}
/**
* Bind values to the bound object
*
* @param array $values
* @param array|null $validationGroup
*
* @return mixed|void
*/
public function bindValues(array $values = [], ?array $validationGroup = null)
{
$objectData = $this->extract();
$hydrator = $this->getHydrator();
$hydratableData = [];
foreach ($this->iterator as $name => $element) {
if ($validationGroup
&& (! array_key_exists($name, $validationGroup) && ! in_array($name, $validationGroup))
) {
continue;
}
if (! array_key_exists($name, $values)) {
if (! ($element instanceof Collection)) {
continue;
}
$values[$name] = [];
}
$value = $values[$name];
if ($element instanceof FieldsetInterface && $element->allowValueBinding()) {
$value = $element->bindValues($value, empty($validationGroup[$name]) ? null : $validationGroup[$name]);
}
// skip post values for disabled elements, get old value from object
if (! $element->getAttribute('disabled')) {
$hydratableData[$name] = $value;
} elseif (array_key_exists($name, $objectData)) {
$hydratableData[$name] = $objectData[$name];
}
}
if (! empty($hydratableData) && $this->object) {
$this->object = $hydrator->hydrate($hydratableData, $this->object);
}
return $this->object;
}
/**
* Set if this fieldset is used as a base fieldset
*
* @param bool $useAsBaseFieldset
* @return Fieldset
*/
public function setUseAsBaseFieldset($useAsBaseFieldset)
{
$this->useAsBaseFieldset = (bool) $useAsBaseFieldset;
return $this;
}
/**
* Is this fieldset use as a base fieldset for a form ?
*
* @return bool
*/
public function useAsBaseFieldset()
{
return $this->useAsBaseFieldset;
}
/**
* Extract values from the bound object
*
* @return array
*/
protected function extract()
{
if (! is_object($this->object)) {
return [];
}
$hydrator = $this->getHydrator();
if (! $hydrator instanceof Hydrator\HydratorInterface) {
return [];
}
$values = $hydrator->extract($this->object);
if (! is_array($values)) {
// Do nothing if the hydrator returned a non-array
return [];
}
// Recursively extract and populate values for nested fieldsets
foreach ($this->fieldsets as $fieldset) {
$name = $fieldset->getName();
if (isset($values[$name])) {
$object = $values[$name];
if ($fieldset->allowObjectBinding($object)) {
$fieldset->setObject($object);
$values[$name] = $fieldset->extract();
}
}
}
return $values;
}
/**
* Make a deep clone of a fieldset
*
* @return void
*/
public function __clone()
{
$items = $this->iterator->toArray(PriorityList::EXTR_BOTH);
$this->elements = [];
$this->fieldsets = [];
$this->iterator = new PriorityList();
$this->iterator->isLIFO(false);
foreach ($items as $name => $item) {
$elementOrFieldset = clone $item['data'];
$this->iterator->insert($name, $elementOrFieldset, $item['priority']);
if ($elementOrFieldset instanceof FieldsetInterface) {
$this->fieldsets[$name] = $elementOrFieldset;
} elseif ($elementOrFieldset instanceof ElementInterface) {
$this->elements[$name] = $elementOrFieldset;
}
}
$this->iterator->rewind();
// Also make a deep copy of the object in case it's used within a collection
if (is_object($this->object)) {
$this->object = clone $this->object;
}
}
}
================================================
FILE: src/Zend/Form/src/FieldsetInterface.php
================================================
'POST',
];
/**
* How to bind values to the attached object
*
* @var int
*/
protected $bindAs = FormInterface::VALUES_NORMALIZED;
/**
* Whether or not to bind values to the bound object on successful validation
*
* @var int
*/
protected $bindOnValidate = FormInterface::BIND_ON_VALIDATE;
/**
* Base fieldset to use for hydrating (if none specified, directly hydrate elements)
*
* @var FieldsetInterface
*/
protected $baseFieldset;
/**
* Data being validated
*
* @var null|array|Traversable
*/
protected $data;
/**
* @var null|InputFilterInterface
*/
protected $filter;
/**
* Whether or not to automatically scan for input filter defaults on
* attached fieldsets and elements
*
* @var bool
*/
protected $useInputFilterDefaults = true;
/**
* Has the input filter defaults been added already ?
*
* @var bool
*/
protected $hasAddedInputFilterDefaults = false;
/**
* Whether or not validation has occurred
*
* @var bool
*/
protected $hasValidated = false;
/**
* Result of last validation operation
*
* @var bool
*/
protected $isValid = false;
/**
* Is the form prepared ?
*
* @var bool
*/
protected $isPrepared = false;
/**
* Prefer form input filter over input filter defaults
*
* @var bool
*/
protected $preferFormInputFilter = true;
/**
* Has preferFormInputFilter been set with setPreferFormInputFilter?
*
* @var bool
*/
protected $hasSetPreferFormInputFilter = false;
/**
* Are the form elements/fieldsets wrapped by the form name ?
*
* @var bool
*/
protected $wrapElements = false;
/**
* Validation group, if any
*
* @var null|array
*/
protected $validationGroup;
/**
* Set options for a form. Accepted options are:
* - prefer_form_input_filter: is form input filter is preferred?
*
* @param array|Traversable $options
* @return self
* @throws Exception\InvalidArgumentException
*/
public function setOptions($options)
{
parent::setOptions($options);
if (isset($options['prefer_form_input_filter'])) {
$this->setPreferFormInputFilter($options['prefer_form_input_filter']);
}
if (isset($options['use_input_filter_defaults'])) {
$this->setUseInputFilterDefaults($options['use_input_filter_defaults']);
}
return $this;
}
/**
* Add an element or fieldset
*
* If $elementOrFieldset is an array or Traversable, passes the argument on
* to the composed factory to create the object before attaching it.
*
* $flags could contain metadata such as the alias under which to register
* the element or fieldset, order in which to prioritize it, etc.
*
* @param array|Traversable|ElementInterface $elementOrFieldset
* @param array $flags
* @return self
*/
public function add($elementOrFieldset, array $flags = [])
{
// TODO: find a better solution than duplicating the factory code, the problem being that if
// $elementOrFieldset is an array, it is passed by value, and we don't get back the concrete ElementInterface
if (is_array($elementOrFieldset)
|| ($elementOrFieldset instanceof Traversable && ! $elementOrFieldset instanceof ElementInterface)
) {
$factory = $this->getFormFactory();
$elementOrFieldset = $factory->create($elementOrFieldset);
}
parent::add($elementOrFieldset, $flags);
if ($elementOrFieldset instanceof Fieldset && $elementOrFieldset->useAsBaseFieldset()) {
$this->baseFieldset = $elementOrFieldset;
}
return $this;
}
/**
* Ensures state is ready for use
*
* Marshalls the input filter, to ensure validation error messages are
* available, and prepares any elements and/or fieldsets that require
* preparation.
*
* @return self
*/
public function prepare()
{
if ($this->isPrepared) {
return $this;
}
$this->getInputFilter();
// If the user wants to, elements names can be wrapped by the form's name
if ($this->wrapElements()) {
$this->prepareElement($this);
} else {
foreach ($this->getIterator() as $elementOrFieldset) {
if ($elementOrFieldset instanceof FormInterface) {
$elementOrFieldset->prepare();
} elseif ($elementOrFieldset instanceof ElementPrepareAwareInterface) {
$elementOrFieldset->prepareElement($this);
}
}
}
$this->isPrepared = true;
return $this;
}
/**
* Ensures state is ready for use. Here, we append the name of the fieldsets to every elements in order to avoid
* name clashes if the same fieldset is used multiple times
*
* @param FormInterface $form
* @return mixed|void
*/
public function prepareElement(FormInterface $form)
{
$name = $this->getName();
foreach ($this->iterator as $elementOrFieldset) {
if ($form->wrapElements()) {
$elementOrFieldset->setName($name . '[' . $elementOrFieldset->getName() . ']');
}
// Recursively prepare elements
if ($elementOrFieldset instanceof ElementPrepareAwareInterface) {
$elementOrFieldset->prepareElement($form);
}
}
}
/**
* Set data to validate and/or populate elements
*
* Typically, also passes data on to the composed input filter.
*
* @param array|\ArrayAccess|Traversable $data
* @return self
* @throws Exception\InvalidArgumentException
*/
public function setData($data)
{
if ($data instanceof Traversable) {
$data = ArrayUtils::iteratorToArray($data);
}
if (! is_array($data)) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects an array or Traversable argument; received "%s"',
__METHOD__,
(is_object($data) ? get_class($data) : gettype($data))
));
}
$this->hasValidated = false;
$this->data = $data;
$this->populateValues($data);
return $this;
}
/**
* Bind an object to the form
*
* Ensures the object is populated with validated values.
*
* @param object $object
* @param int $flags
* @return self
* @throws Exception\InvalidArgumentException
*/
public function bind($object, $flags = FormInterface::VALUES_NORMALIZED)
{
if (! in_array($flags, [FormInterface::VALUES_NORMALIZED, FormInterface::VALUES_RAW])) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects the $flags argument to be one of "%s" or "%s"; received "%s"',
__METHOD__,
'Zend\Form\FormInterface::VALUES_NORMALIZED',
'Zend\Form\FormInterface::VALUES_RAW',
$flags
));
}
$this->baseFieldset?->setObject($object);
$this->bindAs = $flags;
$this->setObject($object);
$data = $this->extract();
$this->populateValues($data, true);
return $this;
}
/**
* Set the hydrator to use when binding an object to the element
*
* @param HydratorInterface $hydrator
* @return FieldsetInterface
*/
public function setHydrator(HydratorInterface $hydrator)
{
$this->baseFieldset?->setHydrator($hydrator);
return parent::setHydrator($hydrator);
}
/**
* Bind values to the bound object
*
* @param array $values
* @return mixed
*/
public function bindValues(array $values = [], ?array $validationGroup = null)
{
if (! is_object($this->object)) {
if ($this->baseFieldset === null || ! $this->baseFieldset->allowValueBinding()) {
return;
}
}
if (! $this->hasValidated() && ! empty($values)) {
$this->setData($values);
if (! $this->isValid()) {
return;
}
} elseif (! $this->isValid) {
return;
}
$filter = $this->getInputFilter();
switch ($this->bindAs) {
case FormInterface::VALUES_RAW:
$data = $filter->getRawValues();
break;
case FormInterface::VALUES_NORMALIZED:
default:
$data = $filter->getValues();
break;
}
$data = $this->prepareBindData($data, $this->data);
$validationGroup = $this->getValidationGroup();
// If there is a base fieldset, only hydrate beginning from the base fieldset
if ($this->baseFieldset !== null) {
$data = array_key_exists($this->baseFieldset->getName(), $data)
? $data[$this->baseFieldset->getName()]
: [];
$this->object = $this->baseFieldset->bindValues($data, $validationGroup[$this->baseFieldset->getName()]);
} else {
$this->object = parent::bindValues($data, $validationGroup);
}
}
/**
* Parse filtered values and return only posted fields for binding
*
* @param array $values
* @param array $match
* @return array
*/
protected function prepareBindData(array $values, array $match)
{
$data = [];
foreach ($values as $name => $value) {
if (! array_key_exists($name, $match)) {
continue;
}
if (is_array($value) && is_array($match[$name])) {
$data[$name] = $this->prepareBindData($value, $match[$name]);
} else {
$data[$name] = $value;
}
}
return $data;
}
/**
* Set flag indicating whether or not to bind values on successful validation
*
* @param int $bindOnValidateFlag
* @return self
* @throws Exception\InvalidArgumentException
*/
public function setBindOnValidate($bindOnValidateFlag)
{
if (! in_array($bindOnValidateFlag, [self::BIND_ON_VALIDATE, self::BIND_MANUAL])) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects the flag to be one of %s::%s or %s::%s',
__METHOD__,
get_class($this),
'BIND_ON_VALIDATE',
get_class($this),
'BIND_MANUAL'
));
}
$this->bindOnValidate = $bindOnValidateFlag;
return $this;
}
/**
* Will we bind values to the bound object on successful validation?
*
* @return bool
*/
public function bindOnValidate()
{
return (static::BIND_ON_VALIDATE === $this->bindOnValidate);
}
/**
* Set the base fieldset to use when hydrating
*
* @param FieldsetInterface $baseFieldset
* @return self
* @throws Exception\InvalidArgumentException
*/
public function setBaseFieldset(FieldsetInterface $baseFieldset)
{
$this->baseFieldset = $baseFieldset;
return $this;
}
/**
* Get the base fieldset to use when hydrating
*
* @return FieldsetInterface
*/
public function getBaseFieldset()
{
return $this->baseFieldset;
}
/**
* Check if the form has been validated
*
* @return bool
*/
public function hasValidated()
{
return $this->hasValidated;
}
/**
* Validate the form
*
* Typically, will proxy to the composed input filter.
*
* @return bool
* @throws Exception\DomainException
*/
public function isValid()
{
if ($this->hasValidated) {
return $this->isValid;
}
$this->isValid = false;
if (! is_array($this->data) && ! is_object($this->object)) {
throw new Exception\DomainException(sprintf(
'%s is unable to validate as there is no data currently set',
__METHOD__
));
}
if (! is_array($this->data)) {
$data = $this->extract();
$this->populateValues($data, true);
if (! is_array($data)) {
throw new Exception\DomainException(sprintf(
'%s is unable to validate as there is no data currently set',
__METHOD__
));
}
$this->data = $data;
}
$filter = $this->getInputFilter();
if (! $filter instanceof InputFilterInterface) {
throw new Exception\DomainException(sprintf(
'%s is unable to validate as there is no input filter present',
__METHOD__
));
}
$filter->setData($this->data);
$filter->setValidationGroup(InputFilterInterface::VALIDATE_ALL);
$validationGroup = $this->getValidationGroup();
if ($validationGroup !== null) {
$this->prepareValidationGroup($this, $this->data, $validationGroup);
$filter->setValidationGroup($validationGroup);
}
$this->isValid = $result = $filter->isValid();
$this->hasValidated = true;
if ($result && $this->bindOnValidate()) {
$this->bindValues();
}
if (! $result) {
$this->setMessages($filter->getMessages());
}
return $result;
}
/**
* Retrieve the validated data
*
* By default, retrieves normalized values; pass one of the
* FormInterface::VALUES_* constants to shape the behavior.
*
* @param int $flag
* @return array|object
* @throws Exception\DomainException
*/
public function getData($flag = FormInterface::VALUES_NORMALIZED)
{
if (! $this->hasValidated) {
throw new Exception\DomainException(sprintf(
'%s cannot return data as validation has not yet occurred',
__METHOD__
));
}
if (($flag !== FormInterface::VALUES_AS_ARRAY) && is_object($this->object)) {
return $this->object;
}
$filter = $this->getInputFilter();
if ($flag === FormInterface::VALUES_RAW) {
return $filter->getRawValues();
}
return $filter->getValues();
}
/**
* Set the validation group (set of values to validate)
*
* Typically, proxies to the composed input filter
*
* @throws Exception\InvalidArgumentException
* @return self
*/
public function setValidationGroup()
{
$argc = func_num_args();
if (0 === $argc) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects at least one argument; none provided',
__METHOD__
));
}
$argv = func_get_args();
$this->hasValidated = false;
if ($argc > 1) {
$this->validationGroup = $argv;
return $this;
}
$arg = array_shift($argv);
if ($arg === FormInterface::VALIDATE_ALL) {
$this->validationGroup = null;
return $this;
}
if (! is_array($arg)) {
$arg = (array) $arg;
}
$this->validationGroup = $arg;
return $this;
}
/**
* Retrieve the current validation group, if any
*
* @return null|array
*/
public function getValidationGroup()
{
return $this->validationGroup;
}
/**
* Prepare the validation group in case Collection elements were used (this function also handle
* the case where elements could have been dynamically added or removed from a collection using JavaScript)
*
* @param FieldsetInterface $formOrFieldset
* @param array $data
* @param array $validationGroup
*/
protected function prepareValidationGroup(FieldsetInterface $formOrFieldset, array $data, array &$validationGroup)
{
foreach ($validationGroup as $key => &$value) {
if (! $formOrFieldset->has($key)) {
continue;
}
$fieldset = $formOrFieldset->iterator->get($key);
if ($fieldset instanceof Collection) {
if (! isset($data[$key]) && $fieldset->getCount() == 0) {
unset($validationGroup[$key]);
continue;
}
$values = [];
if (isset($data[$key])) {
foreach (array_keys($data[$key]) as $cKey) {
$values[$cKey] = $value;
}
}
$value = $values;
}
if (! isset($data[$key])) {
$data[$key] = [];
}
$this->prepareValidationGroup($fieldset, $data[$key], $validationGroup[$key]);
}
}
/**
* Set the input filter used by this form
*
* @param InputFilterInterface $inputFilter
* @return self
*/
public function setInputFilter(InputFilterInterface $inputFilter)
{
$this->hasValidated = false;
$this->hasAddedInputFilterDefaults = false;
$this->filter = $inputFilter;
if (false === $this->hasSetPreferFormInputFilter) {
$this->preferFormInputFilter = false;
}
return $this;
}
/**
* Retrieve input filter used by this form
*
* @return null|InputFilterInterface
*/
public function getInputFilter()
{
if ($this->object instanceof InputFilterAwareInterface) {
if (null == $this->baseFieldset) {
$this->filter = $this->object->getInputFilter();
} else {
$name = $this->baseFieldset->getName();
if (! $this->filter instanceof InputFilterInterface || ! $this->filter->has($name)) {
$filter = new InputFilter();
$filter->setFactory($this->getFormFactory()->getInputFilterFactory());
$filter->add($this->object->getInputFilter(), $name);
$this->filter = $filter;
}
}
}
if (! isset($this->filter)) {
$this->filter = new InputFilter();
$this->filter->setFactory($this->getFormFactory()->getInputFilterFactory());
}
if (! $this->hasAddedInputFilterDefaults
&& $this->filter instanceof InputFilterInterface
&& $this->useInputFilterDefaults()
) {
$this->attachInputFilterDefaults($this->filter, $this);
$this->hasAddedInputFilterDefaults = true;
}
return $this->filter;
}
/**
* Set flag indicating whether or not to scan elements and fieldsets for defaults
*
* @param bool $useInputFilterDefaults
* @return self
*/
public function setUseInputFilterDefaults($useInputFilterDefaults)
{
$this->useInputFilterDefaults = (bool) $useInputFilterDefaults;
return $this;
}
/**
* Should we use input filter defaults from elements and fieldsets?
*
* @return bool
*/
public function useInputFilterDefaults()
{
return $this->useInputFilterDefaults;
}
/**
* Set flag indicating whether or not to prefer the form input filter over element and fieldset defaults
*
* @param bool $preferFormInputFilter
* @return self
*/
public function setPreferFormInputFilter($preferFormInputFilter)
{
$this->preferFormInputFilter = (bool) $preferFormInputFilter;
$this->hasSetPreferFormInputFilter = true;
return $this;
}
/**
* Should we use form input filter over element input filter defaults from elements and fieldsets?
*
* @return bool
*/
public function getPreferFormInputFilter()
{
return $this->preferFormInputFilter;
}
/**
* Attach defaults provided by the elements to the input filter
*
* @param InputFilterInterface $inputFilter
* @param FieldsetInterface $fieldset Fieldset to traverse when looking for default inputs
* @return void
*/
public function attachInputFilterDefaults(InputFilterInterface $inputFilter, FieldsetInterface $fieldset)
{
$formFactory = $this->getFormFactory();
$inputFactory = $formFactory->getInputFilterFactory();
if ($fieldset instanceof Collection && $fieldset->getTargetElement() instanceof FieldsetInterface) {
$elements = $fieldset->getTargetElement()->getElements();
} else {
$elements = $fieldset->getElements();
}
if (! $fieldset instanceof Collection
|| ! $fieldset->getTargetElement() instanceof FieldsetInterface
|| $inputFilter instanceof CollectionInputFilter
) {
foreach ($elements as $name => $element) {
if ($this->preferFormInputFilter && $inputFilter->has($name)) {
continue;
}
if (! $element instanceof InputProviderInterface) {
if ($inputFilter->has($name)) {
continue;
}
// Create a new empty default input for this element
$spec = ['name' => $name, 'required' => false];
$input = $inputFactory->createInput($spec);
} else {
// Create an input based on the specification returned from the element
$spec = $element->getInputSpecification();
$input = $inputFactory->createInput($spec);
if ($inputFilter->has($name) && $inputFilter instanceof ReplaceableInputInterface) {
$input->merge($inputFilter->get($name));
$inputFilter->replace($input, $name);
continue;
}
// If we are dealing with a collection input filter, check
// the input filter it composes for an element of the same
// name as was done above.
if ($inputFilter instanceof CollectionInputFilter
&& $inputFilter->getInputFilter()->has($name)
&& $inputFilter->getInputFilter() instanceof ReplaceableInputInterface
) {
$collectionInputFilter = $inputFilter->getInputFilter();
$input->merge($collectionInputFilter->get($name));
$collectionInputFilter->replace($input, $name);
continue;
}
}
// Add element input filter to CollectionInputFilter
if ($inputFilter instanceof CollectionInputFilter && ! $inputFilter->getInputFilter()->has($name)) {
$inputFilter->getInputFilter()->add($input, $name);
} else {
$inputFilter->add($input, $name);
}
}
if ($fieldset === $this && $fieldset instanceof InputFilterProviderInterface) {
foreach ($fieldset->getInputFilterSpecification() as $name => $spec) {
$input = $inputFactory->createInput($spec);
$inputFilter->add($input, $name);
}
}
}
foreach ($fieldset->getFieldsets() as $name => $childFieldset) {
if (! $childFieldset instanceof InputFilterProviderInterface) {
if (! $inputFilter->has($name)) {
// Add a new empty input filter if it does not exist (or the fieldset's object input filter),
// so that elements of nested fieldsets can be recursively added
if ($childFieldset->getObject() instanceof InputFilterAwareInterface) {
$inputFilter->add($childFieldset->getObject()->getInputFilter(), $name);
} else {
// Add input filter for collections via getInputFilterSpecification()
if ($childFieldset instanceof Collection
&& $childFieldset->getTargetElement() instanceof InputFilterProviderInterface
&& $childFieldset->getTargetElement()->getInputFilterSpecification()
) {
$collectionContainerFilter = new CollectionInputFilter();
$spec = $childFieldset->getTargetElement()->getInputFilterSpecification();
$filter = $inputFactory->createInputFilter($spec);
$collectionContainerFilter->setInputFilter($filter);
$inputFilter->add($collectionContainerFilter, $name);
// We need to copy the inputs to the collection input filter
if ($inputFilter instanceof CollectionInputFilter) {
$inputFilter = $this->addInputsToCollectionInputFilter($inputFilter);
}
// Add child elements from target element
$childFieldset = $childFieldset->getTargetElement();
} else {
$inputFilter->add(new InputFilter(), $name);
}
}
}
$fieldsetFilter = $inputFilter->get($name);
if (! $fieldsetFilter instanceof InputFilterInterface) {
// Input attached for fieldset, not input filter; nothing more to do.
continue;
}
// Traverse the elements of the fieldset, and attach any
// defaults to the fieldset's input filter
$this->attachInputFilterDefaults($fieldsetFilter, $childFieldset);
continue;
}
if ($inputFilter->has($name)) {
// if we already have an input/filter by this name, use it
continue;
}
// Create an input filter based on the specification returned from the fieldset
$spec = $childFieldset->getInputFilterSpecification();
$filter = $inputFactory->createInputFilter($spec);
$inputFilter->add($filter, $name);
// Recursively attach sub filters
$this->attachInputFilterDefaults($filter, $childFieldset);
// We need to copy the inputs to the collection input filter to ensure that all sub filters are added
if ($inputFilter instanceof CollectionInputFilter) {
$inputFilter = $this->addInputsToCollectionInputFilter($inputFilter);
}
}
}
/**
* Add inputs to CollectionInputFilter
*
* @param CollectionInputFilter $inputFilter
* @return CollectionInputFilter
*/
private function addInputsToCollectionInputFilter(CollectionInputFilter $inputFilter)
{
foreach ($inputFilter->getInputs() as $name => $input) {
if (! $inputFilter->getInputFilter()->has($name)) {
$inputFilter->getInputFilter()->add($input, $name);
}
}
return $inputFilter;
}
/**
* Are the form elements/fieldsets names wrapped by the form name ?
*
* @param bool $wrapElements
* @return self
*/
public function setWrapElements($wrapElements)
{
$this->wrapElements = (bool) $wrapElements;
return $this;
}
/**
* If true, form elements/fieldsets name's are wrapped around the form name itself
*
* @return bool
*/
public function wrapElements()
{
return $this->wrapElements;
}
/**
* {@inheritDoc}
*
* @param bool $onlyBase
*/
public function populateValues($data, $onlyBase = false)
{
if ($onlyBase && $this->baseFieldset !== null) {
$name = $this->baseFieldset->getName();
if (array_key_exists($name, $data)) {
$this->baseFieldset->populateValues($data[$name]);
}
} else {
parent::populateValues($data);
}
}
/**
* Recursively extract values for elements and sub-fieldsets
*
* @return array
*/
protected function extract()
{
if (null !== $this->baseFieldset) {
$name = $this->baseFieldset->getName();
$values[$name] = $this->baseFieldset->extract();
} else {
$values = parent::extract();
}
return $values;
}
}
================================================
FILE: src/Zend/Form/src/FormAbstractServiceFactory.php
================================================
getConfig($container);
$config = $config[$requestedName];
$factory = $this->getFormFactory($container);
$this->marshalInputFilter($config, $container, $factory);
return $factory->createForm($config);
}
/**
* Can we create the requested service? (v3)
*
* @param ContainerInterface $container
* @param string $requestedName
* @return bool
*/
public function canCreate(ContainerInterface $container, $requestedName)
{
// avoid infinite loops when looking up config
if ($requestedName == 'config') {
return false;
}
$config = $this->getConfig($container);
if (empty($config)) {
return false;
}
return (isset($config[$requestedName])
&& is_array($config[$requestedName])
&& ! empty($config[$requestedName]));
}
/**
* Can we create the requested service? (v2)
*
* @param ServiceLocatorInterface $serviceLocator
* @param string $name Service name (as resolved by ServiceManager)
* @param string $requestedName Name by which service was requested
* @return bool
*/
public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
{
return $this->canCreate($serviceLocator, $requestedName);
}
/**
* Create a form (v2)
*
* @param ServiceLocatorInterface $serviceLocator
* @param string $name Service name (as resolved by ServiceManager)
* @param string $requestedName Name by which service was requested
* @return Form
*/
public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
{
return $this($serviceLocator, $requestedName);
}
/**
* Get forms configuration, if any
*
* @param ServiceLocatorInterface $container
* @return array
*/
protected function getConfig(ContainerInterface $container)
{
if ($this->config !== null) {
return $this->config;
}
if (! $container->has('config')) {
$this->config = [];
return $this->config;
}
$config = $container->get('config');
if (! isset($config[$this->configKey])
|| ! is_array($config[$this->configKey])
) {
$this->config = [];
return $this->config;
}
$this->config = $config[$this->configKey];
return $this->config;
}
/**
* Retrieve the form factory, creating it if necessary
*
* @param ContainerInterface $services
* @return Factory
*/
protected function getFormFactory(ContainerInterface $container)
{
if ($this->factory instanceof Factory) {
return $this->factory;
}
$elements = null;
if ($container->has('FormElementManager')) {
$elements = $container->get('FormElementManager');
}
$this->factory = new Factory($elements);
return $this->factory;
}
/**
* Marshal the input filter into the configuration
*
* If an input filter is specified:
* - if the InputFilterManager is present, checks if it's there; if so,
* retrieves it and resets the specification to the instance.
* - otherwise, pulls the input filter factory from the form factory, and
* attaches the FilterManager and ValidatorManager to it.
*
* @param array $config
* @param ContainerInterface $container
* @param Factory $formFactory
*/
protected function marshalInputFilter(array &$config, ContainerInterface $container, Factory $formFactory)
{
if (! isset($config['input_filter'])) {
return;
}
if ($config['input_filter'] instanceof InputFilterInterface) {
return;
}
if (is_string($config['input_filter'])
&& $container->has('InputFilterManager')
) {
$inputFilters = $container->get('InputFilterManager');
if ($inputFilters->has($config['input_filter'])) {
$config['input_filter'] = $inputFilters->get($config['input_filter']);
return;
}
}
$inputFilterFactory = $formFactory->getInputFilterFactory();
$inputFilterFactory->getDefaultFilterChain()->setPluginManager($container->get('FilterManager'));
$inputFilterFactory->getDefaultValidatorChain()->setPluginManager($container->get('ValidatorManager'));
}
}
================================================
FILE: src/Zend/Form/src/FormElementManager/FormElementManagerTrait.php
================================================
$options];
}
if (! $this->has($name)) {
if (! $this->autoAddInvokableClass || ! class_exists($name)) {
throw new Exception\InvalidElementException(sprintf(
'A plugin by the name "%s" was not found in the plugin manager %s',
$name,
get_class($this)
));
}
$this->setInvokableClass($name, $name);
}
return parent::get($name, $options, $usePeeringServiceManagers);
}
/**
* Try to pull hydrator from the creation context, or instantiates it from its name
*
* @param string $hydratorName
* @return mixed
* @throws Exception\DomainException
*/
public function getHydratorFromName($hydratorName)
{
$services = $this->creationContext ?? $this->serviceLocator; // v2
if ($services && $services->has('HydratorManager')) {
$hydrators = $services->get('HydratorManager');
if ($hydrators->has($hydratorName)) {
return $hydrators->get($hydratorName);
}
}
if ($services && $services->has($hydratorName)) {
return $services->get($hydratorName);
}
if (! class_exists($hydratorName)) {
throw new Exception\DomainException(sprintf(
'Expects string hydrator name to be a valid class name; received "%s"',
$hydratorName
));
}
$hydrator = new $hydratorName;
return $hydrator;
}
/**
* Try to pull factory from the creation context, or instantiates it from its name
*
* @param string $factoryName
* @return mixed
* @throws Exception\DomainException
*/
public function getFactoryFromName($factoryName)
{
$services = $this->creationContext ?? $this->serviceLocator; // v2
if ($services && $services->has($factoryName)) {
return $services->get($factoryName);
}
if (! class_exists($factoryName)) {
throw new Exception\DomainException(sprintf(
'Expects string factory name to be a valid class name; received "%s"',
$factoryName
));
}
$factory = new $factoryName;
return $factory;
}
}
================================================
FILE: src/Zend/Form/src/FormElementManager.php
================================================
Element\Button::class,
'captcha' => Element\Captcha::class,
'checkbox' => Element\Checkbox::class,
'collection' => Element\Collection::class,
'color' => Element\Color::class,
'csrf' => Element\Csrf::class,
'date' => Element\Date::class,
'dateselect' => Element\DateSelect::class,
'datetime' => Element\DateTime::class,
'datetimelocal' => Element\DateTimeLocal::class,
'datetimeselect' => Element\DateTimeSelect::class,
'element' => Element::class,
'email' => Element\Email::class,
'fieldset' => Fieldset::class,
'file' => Element\File::class,
'form' => Form::class,
'hidden' => Element\Hidden::class,
'image' => Element\Image::class,
'month' => Element\Month::class,
'monthselect' => Element\MonthSelect::class,
'multicheckbox' => Element\MultiCheckbox::class,
'number' => Element\Number::class,
'password' => Element\Password::class,
'radio' => Element\Radio::class,
'range' => Element\Range::class,
'select' => Element\Select::class,
'submit' => Element\Submit::class,
'text' => Element\Text::class,
'textarea' => Element\Textarea::class,
'time' => Element\Time::class,
'url' => Element\Url::class,
'week' => Element\Week::class,
];
/**
* Factories for default set of helpers
*
* @var array
*/
protected $factories = [
Element\Button::class => ElementFactory::class,
Element\Captcha::class => ElementFactory::class,
Element\Checkbox::class => ElementFactory::class,
Element\Collection::class => ElementFactory::class,
Element\Color::class => ElementFactory::class,
Element\Csrf::class => ElementFactory::class,
Element\Date::class => ElementFactory::class,
Element\DateSelect::class => ElementFactory::class,
Element\DateTime::class => ElementFactory::class,
Element\DateTimeLocal::class => ElementFactory::class,
Element\DateTimeSelect::class => ElementFactory::class,
Element::class => ElementFactory::class,
Element\Email::class => ElementFactory::class,
Fieldset::class => ElementFactory::class,
Element\File::class => ElementFactory::class,
Form::class => ElementFactory::class,
Element\Hidden::class => ElementFactory::class,
Element\Image::class => ElementFactory::class,
Element\Month::class => ElementFactory::class,
Element\MonthSelect::class => ElementFactory::class,
Element\MultiCheckbox::class => ElementFactory::class,
Element\Number::class => ElementFactory::class,
Element\Password::class => ElementFactory::class,
Element\Radio::class => ElementFactory::class,
Element\Range::class => ElementFactory::class,
Element\Select::class => ElementFactory::class,
Element\Submit::class => ElementFactory::class,
Element\Text::class => ElementFactory::class,
Element\Textarea::class => ElementFactory::class,
Element\Time::class => ElementFactory::class,
Element\Url::class => ElementFactory::class,
Element\Week::class => ElementFactory::class,
// v2 normalized variants
'zendformelementbutton' => ElementFactory::class,
'zendformelementcaptcha' => ElementFactory::class,
'zendformelementcheckbox' => ElementFactory::class,
'zendformelementcollection' => ElementFactory::class,
'zendformelementcolor' => ElementFactory::class,
'zendformelementcsrf' => ElementFactory::class,
'zendformelementdate' => ElementFactory::class,
'zendformelementdateselect' => ElementFactory::class,
'zendformelementdatetime' => ElementFactory::class,
'zendformelementdatetimelocal' => ElementFactory::class,
'zendformelementdatetimeselect' => ElementFactory::class,
'zendformelement' => ElementFactory::class,
'zendformelementemail' => ElementFactory::class,
'zendformfieldset' => ElementFactory::class,
'zendformelementfile' => ElementFactory::class,
'zendformform' => ElementFactory::class,
'zendformelementhidden' => ElementFactory::class,
'zendformelementimage' => ElementFactory::class,
'zendformelementmonth' => ElementFactory::class,
'zendformelementmonthselect' => ElementFactory::class,
'zendformelementmulticheckbox' => ElementFactory::class,
'zendformelementnumber' => ElementFactory::class,
'zendformelementpassword' => ElementFactory::class,
'zendformelementradio' => ElementFactory::class,
'zendformelementrange' => ElementFactory::class,
'zendformelementselect' => ElementFactory::class,
'zendformelementsubmit' => ElementFactory::class,
'zendformelementtext' => ElementFactory::class,
'zendformelementtextarea' => ElementFactory::class,
'zendformelementtime' => ElementFactory::class,
'zendformelementurl' => ElementFactory::class,
'zendformelementweek' => ElementFactory::class,
];
/**
* Don't share form elements by default (v3)
*
* @var bool
*/
protected $sharedByDefault = false;
/**
* Don't share form elements by default (v2)
*
* @var bool
*/
protected $shareByDefault = false;
/**
* Interface all plugins managed by this class must implement.
* @var string
*/
protected $instanceOf = ElementInterface::class;
/**
* Constructor
*
* Overrides parent constructor in order to add the initializer methods injectFactory()
* and callElementInit().
*
* @param null|ConfigInterface|ContainerInterface $configOrContainerInstance
* @param array $v3config If $configOrContainerInstance is a container, this
* value will be passed to the parent constructor.
*/
public function __construct($configInstanceOrParentLocator = null, array $v3config = [])
{
// Provide default initializers, ensuring correct order
array_unshift($this->initializers, [$this, 'injectFactory']);
$this->initializers[] = [ $this, 'callElementInit' ];
parent::__construct($configInstanceOrParentLocator, $v3config);
}
/**
* Inject the factory to any element that implements FormFactoryAwareInterface
*
* @param mixed $instance Instance to inspect and potentially inject.
* @param ContainerInterface $container Container passed to initializer.
*/
public function injectFactory($instance, ContainerInterface $container)
{
// Need to retrieve the parent container
$container = $container->getServiceLocator() ?: $container;
if (! $instance instanceof FormFactoryAwareInterface) {
return;
}
$factory = $instance->getFormFactory();
$factory->setFormElementManager($this);
if ($container && $container->has('InputFilterManager')) {
$inputFilters = $container->get('InputFilterManager');
$factory->getInputFilterFactory()->setInputFilterManager($inputFilters);
}
}
/**
* Call init() on any element that implements InitializableInterface
*
* @param mixed $instance Instance to inspect and optionally initialize.
*/
public function callElementInit($instance)
{
if ($instance instanceof InitializableInterface) {
$instance->init();
}
}
/**
* Override setInvokableClass
*
* Overrides setInvokableClass to:
*
* - add a factory mapping $invokableClass to ElementFactory::class
* - alias $name to $invokableClass
*
* @param string $name
* @param string $invokableClass
* @param null|bool $shared Ignored.
* @return self
*/
public function setInvokableClass($name, $invokableClass, $shared = null)
{
if (! $this->has($invokableClass)) {
$this->setFactory($invokableClass, ElementFactory::class);
}
if ($invokableClass !== $name) {
$this->setAlias($name, $invokableClass);
}
return $this;
}
/**
* Validate the plugin is of the expected type.
*
* @param mixed $plugin
* @throws Exception\InvalidElementException
*/
public function validatePlugin($plugin)
{
if (! $plugin instanceof $this->instanceOf) {
throw new Exception\InvalidElementException(sprintf(
'%s can only create instances of %s; %s is invalid',
get_class($this),
$this->instanceOf,
(is_object($plugin) ? get_class($plugin) : gettype($plugin))
));
}
}
/**
* Overrides parent::addInitializer in order to ensure default initializers are in expected positions.
*
* Always pushes `injectFactory` to top of initializer stack, and
* `callElementInit` to the bottom.
*
* {@inheritDoc}
*/
public function addInitializer($initializer, $topOfStack = true)
{
$firstInitializer = [$this, 'injectFactory'];
$lastInitializer = [$this, 'callElementInit'];
foreach ([$firstInitializer, $lastInitializer] as $default) {
if (false === ($index = array_search($default, $this->initializers))) {
continue;
}
unset($this->initializers[$index]);
}
parent::addInitializer($initializer, $topOfStack);
array_unshift($this->initializers, $firstInitializer);
$this->initializers[] = $lastInitializer;
return $this;
}
}
================================================
FILE: src/Zend/Form/src/FormElementManagerFactory.php
================================================
isV3Container()
? new FormElementManager\FormElementManagerV3Polyfill($container, $options ?: [])
: new FormElementManager\FormElementManagerV2Polyfill($container, $options ?: []);
// If this is in a zend-mvc application, the ServiceListener will inject
// merged configuration during bootstrap.
if ($container->has('ServiceListener')) {
return $pluginManager;
}
// If we do not have a config service, nothing more to do
if (! $container->has('config')) {
return $pluginManager;
}
$config = $container->get('config');
// If we do not have form_elements configuration, nothing more to do
if (! isset($config['form_elements']) || ! is_array($config['form_elements'])) {
return $pluginManager;
}
// Wire service configuration for forms and elements
(new Config($config['form_elements']))->configureServiceManager($pluginManager);
return $pluginManager;
}
/**
* {@inheritDoc}
*
* @return AbstractPluginManager
*/
public function createService(ServiceLocatorInterface $container, $name = null, $requestedName = null)
{
return $this(
$container,
$requestedName ?: __NAMESPACE__ . '\FormElementManager',
$this->creationOptions
);
}
/**
* zend-servicemanager v2 support for invocation options.
*
* @param array $options
* @return void
*/
public function setCreationOptions(array $options)
{
$this->creationOptions = $options;
}
/**
* Are we running under zend-servicemanager v3?
*
* @return bool
*/
private function isV3Container()
{
return method_exists(AbstractPluginManager::class, 'configure');
}
}
================================================
FILE: src/Zend/Form/src/FormFactoryAwareInterface.php
================================================
factory = $factory;
return $this;
}
}
================================================
FILE: src/Zend/Form/src/FormInterface.php
================================================
filterSpec;
}
/**
* @param array|Traversable $filterSpec
*/
public function setInputFilterSpecification($filterSpec)
{
$this->filterSpec = $filterSpec;
}
/**
* Set options for a fieldset. Accepted options are:
* - input_filter_spec: specification to be returned by getInputFilterSpecification
*
* @param array|Traversable $options
* @return Element|ElementInterface
* @throws Exception\InvalidArgumentException
*/
public function setOptions($options)
{
parent::setOptions($options);
if (isset($options['input_filter_spec'])) {
$this->setInputFilterSpecification($options['input_filter_spec']);
}
return $this;
}
}
================================================
FILE: src/Zend/Form/src/LabelAwareInterface.php
================================================
labelAttributes = $labelAttributes;
return $this;
}
/**
* Get the attributes to use with the label
*
* @return array
*/
public function getLabelAttributes()
{
return $this->labelAttributes;
}
/**
* Set many label options at once
*
* Implementation will decide if this will overwrite or merge.
*
* @param array|Traversable $arrayOrTraversable
* @return Element|ElementInterface
* @throws Exception\InvalidArgumentException
*/
public function setLabelOptions($arrayOrTraversable)
{
if (! is_array($arrayOrTraversable) && ! $arrayOrTraversable instanceof Traversable) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects an array or Traversable argument; received "%s"',
__METHOD__,
(is_object($arrayOrTraversable) ? get_class($arrayOrTraversable) : gettype($arrayOrTraversable))
));
}
foreach ($arrayOrTraversable as $key => $value) {
$this->setLabelOption($key, $value);
}
return $this;
}
/**
* Get label specific options
*
* @return array
*/
public function getLabelOptions()
{
return $this->labelOptions;
}
/**
* Clear all label options
*
* @return Element|ElementInterface
*/
public function clearLabelOptions()
{
$this->labelOptions = [];
return $this;
}
/**
* Remove many attributes at once
*
* @param array $keys
* @return ElementInterface
*/
public function removeLabelOptions(array $keys)
{
foreach ($keys as $key) {
unset($this->labelOptions[$key]);
}
return $this;
}
/**
* Set a single label optionn
*
* @param string $key
* @param mixed $value
* @return Element|ElementInterface
*/
public function setLabelOption($key, $value)
{
$this->labelOptions[$key] = $value;
return $this;
}
/**
* Retrieve a single label option
*
* @param $key
* @return mixed|null
*/
public function getLabelOption($key)
{
if (! array_key_exists($key, $this->labelOptions)) {
return;
}
return $this->labelOptions[$key];
}
/**
* Remove a single label option
*
* @param string $key
* @return ElementInterface
*/
public function removeLabelOption($key)
{
unset($this->labelOptions[$key]);
return $this;
}
/**
* Does the element has a specific label option ?
*
* @param string $key
* @return bool
*/
public function hasLabelOption($key)
{
return array_key_exists($key, $this->labelOptions);
}
}
================================================
FILE: src/Zend/Form/src/Module.php
================================================
$provider->getDependencyConfig(),
'view_helpers' => $provider->getViewHelperConfig(),
];
}
/**
* Register a specification for the FormElementManager with the ServiceListener.
*
* @param \Zend\ModuleManager\ModuleManager $moduleManager
* @return void
*/
public function init($moduleManager)
{
$event = $moduleManager->getEvent();
$container = $event->getParam('ServiceManager');
$serviceListener = $container->get('ServiceListener');
$serviceListener->addServiceManager(
'FormElementManager',
'form_elements',
'Zend\ModuleManager\Feature\FormElementProviderInterface',
'getFormElementConfig'
);
}
}
================================================
FILE: src/Zend/Form/src/View/Helper/AbstractHelper.php
================================================
true,
];
/**
* The default translatable HTML attribute prefixes
*
* @var array
*/
protected static $defaultTranslatableHtmlAttributePrefixes = [];
/**
* Standard boolean attributes, with expected values for enabling/disabling
*
* @var array
*/
protected $booleanAttributes = [
'autofocus' => ['on' => 'autofocus', 'off' => ''],
'checked' => ['on' => 'checked', 'off' => ''],
'disabled' => ['on' => 'disabled', 'off' => ''],
'multiple' => ['on' => 'multiple', 'off' => ''],
'readonly' => ['on' => 'readonly', 'off' => ''],
'required' => ['on' => 'required', 'off' => ''],
'selected' => ['on' => 'selected', 'off' => ''],
];
/**
* Translatable attributes
*
* @var array
*/
protected $translatableAttributes = [
'placeholder' => true,
];
/**
* Prefixes of translatable HTML attributes
*
* @var array
*/
protected $translatableAttributePrefixes = [];
/**
* @var Doctype
*/
protected $doctypeHelper;
/**
* @var EscapeHtml
*/
protected $escapeHtmlHelper;
/**
* @var EscapeHtmlAttr
*/
protected $escapeHtmlAttrHelper;
/**
* Attributes globally valid for all tags
*
* @var array
*/
protected $validGlobalAttributes = [
'accesskey' => true,
'class' => true,
'contenteditable' => true,
'contextmenu' => true,
'dir' => true,
'draggable' => true,
'dropzone' => true,
'hidden' => true,
'id' => true,
'lang' => true,
'onabort' => true,
'onblur' => true,
'oncanplay' => true,
'oncanplaythrough' => true,
'onchange' => true,
'onclick' => true,
'oncontextmenu' => true,
'ondblclick' => true,
'ondrag' => true,
'ondragend' => true,
'ondragenter' => true,
'ondragleave' => true,
'ondragover' => true,
'ondragstart' => true,
'ondrop' => true,
'ondurationchange' => true,
'onemptied' => true,
'onended' => true,
'onerror' => true,
'onfocus' => true,
'oninput' => true,
'oninvalid' => true,
'onkeydown' => true,
'onkeypress' => true,
'onkeyup' => true,
'onload' => true,
'onloadeddata' => true,
'onloadedmetadata' => true,
'onloadstart' => true,
'onmousedown' => true,
'onmousemove' => true,
'onmouseout' => true,
'onmouseover' => true,
'onmouseup' => true,
'onmousewheel' => true,
'onpause' => true,
'onplay' => true,
'onplaying' => true,
'onprogress' => true,
'onratechange' => true,
'onreadystatechange' => true,
'onreset' => true,
'onscroll' => true,
'onseeked' => true,
'onseeking' => true,
'onselect' => true,
'onshow' => true,
'onstalled' => true,
'onsubmit' => true,
'onsuspend' => true,
'ontimeupdate' => true,
'onvolumechange' => true,
'onwaiting' => true,
'role' => true,
'spellcheck' => true,
'style' => true,
'tabindex' => true,
'title' => true,
'xml:base' => true,
'xml:lang' => true,
'xml:space' => true,
];
/**
* Attribute prefixes valid for all tags
*
* @var array
*/
protected $validTagAttributePrefixes = [
'data-',
'aria-',
'x-',
];
/**
* Attributes valid for the tag represented by this helper
*
* This should be overridden in extending classes
*
* @var array
*/
protected $validTagAttributes = [
];
/**
* Set value for doctype
*
* @param string $doctype
* @return AbstractHelper
*/
public function setDoctype($doctype)
{
$this->getDoctypeHelper()->setDoctype($doctype);
return $this;
}
/**
* Get value for doctype
*
* @return string
*/
public function getDoctype()
{
return $this->getDoctypeHelper()->getDoctype();
}
/**
* Set value for character encoding
*
* @param string $encoding
* @return AbstractHelper
*/
public function setEncoding($encoding)
{
$this->getEscapeHtmlHelper()->setEncoding($encoding);
$this->getEscapeHtmlAttrHelper()->setEncoding($encoding);
return $this;
}
/**
* Get character encoding
*
* @return string
*/
public function getEncoding()
{
return $this->getEscapeHtmlHelper()->getEncoding();
}
/**
* Create a string of all attribute/value pairs
*
* Escapes all attribute values
*
* @param array $attributes
* @return string
*/
public function createAttributesString(array $attributes)
{
$attributes = $this->prepareAttributes($attributes);
$escape = $this->getEscapeHtmlHelper();
$escapeAttr = $this->getEscapeHtmlAttrHelper();
$strings = [];
foreach ($attributes as $key => $value) {
$key = strtolower($key);
if (! $value && isset($this->booleanAttributes[$key])) {
// Skip boolean attributes that expect empty string as false value
if ('' === $this->booleanAttributes[$key]['off']) {
continue;
}
}
//check if attribute is translatable and translate it
$value = $this->translateHtmlAttributeValue($key, $value);
// @todo Escape event attributes like AbstractHtmlElement view helper does in htmlAttribs ??
try {
$escapedAttribute = $escapeAttr($value);
$strings[] = sprintf('%s="%s"', $escape($key), $escapedAttribute);
} catch (EscaperException) {
// If an escaper exception happens, escape only the key, and use a blank value.
$strings[] = sprintf('%s=""', $escape($key));
}
}
return implode(' ', $strings);
}
/**
* Get the ID of an element
*
* If no ID attribute present, attempts to use the name attribute.
* If no name attribute is present, either, returns null.
*
* @param ElementInterface $element
* @return null|string
*/
public function getId(ElementInterface $element)
{
$id = $element->getAttribute('id');
if (null !== $id) {
return $id;
}
return $element->getName();
}
/**
* Get the closing bracket for an inline tag
*
* Closes as either "/>" for XHTML doctypes or ">" otherwise.
*
* @return string
*/
public function getInlineClosingBracket()
{
$doctypeHelper = $this->getDoctypeHelper();
if ($doctypeHelper->isXhtml()) {
return '/>';
}
return '>';
}
/**
* Retrieve the doctype helper
*
* @return Doctype
*/
protected function getDoctypeHelper()
{
if ($this->doctypeHelper) {
return $this->doctypeHelper;
}
if (method_exists($this->view, 'plugin')) {
$this->doctypeHelper = $this->view->plugin('doctype');
}
if (! $this->doctypeHelper instanceof Doctype) {
$this->doctypeHelper = new Doctype();
}
return $this->doctypeHelper;
}
/**
* Retrieve the escapeHtml helper
*
* @return EscapeHtml
*/
protected function getEscapeHtmlHelper()
{
if ($this->escapeHtmlHelper) {
return $this->escapeHtmlHelper;
}
if (method_exists($this->view, 'plugin')) {
$this->escapeHtmlHelper = $this->view->plugin('escapehtml');
}
if (! $this->escapeHtmlHelper instanceof EscapeHtml) {
$this->escapeHtmlHelper = new EscapeHtml();
}
return $this->escapeHtmlHelper;
}
/**
* Retrieve the escapeHtmlAttr helper
*
* @return EscapeHtmlAttr
*/
protected function getEscapeHtmlAttrHelper()
{
if ($this->escapeHtmlAttrHelper) {
return $this->escapeHtmlAttrHelper;
}
if (method_exists($this->view, 'plugin')) {
$this->escapeHtmlAttrHelper = $this->view->plugin('escapehtmlattr');
}
if (! $this->escapeHtmlAttrHelper instanceof EscapeHtmlAttr) {
$this->escapeHtmlAttrHelper = new EscapeHtmlAttr();
}
return $this->escapeHtmlAttrHelper;
}
/**
* Prepare attributes for rendering
*
* Ensures appropriate attributes are present (e.g., if "name" is present,
* but no "id", sets the latter to the former).
*
* Removes any invalid attributes
*
* @param array $attributes
* @return array
*/
protected function prepareAttributes(array $attributes)
{
foreach ($attributes as $key => $value) {
$attribute = strtolower($key);
if (! isset($this->validGlobalAttributes[$attribute])
&& ! isset($this->validTagAttributes[$attribute])
&& ! $this->hasAllowedPrefix($attribute)
) {
unset($attributes[$key]);
continue;
}
// Normalize attribute key, if needed
if ($attribute != $key) {
unset($attributes[$key]);
$attributes[$attribute] = $value;
}
// Normalize boolean attribute values
if (isset($this->booleanAttributes[$attribute])) {
$attributes[$attribute] = $this->prepareBooleanAttributeValue($attribute, $value);
}
}
return $attributes;
}
/**
* Prepare a boolean attribute value
*
* Prepares the expected representation for the boolean attribute specified.
*
* @param string $attribute
* @param mixed $value
* @return string
*/
protected function prepareBooleanAttributeValue($attribute, $value)
{
if (! is_bool($value) && in_array($value, $this->booleanAttributes[$attribute])) {
return $value;
}
$value = (bool) $value;
return ($value
? $this->booleanAttributes[$attribute]['on']
: $this->booleanAttributes[$attribute]['off']
);
}
/**
* Translates the value of the HTML attribute if it should be translated and this view helper has a translator
*
* @param string $key
* @param string $value
*
* @return string
*/
protected function translateHtmlAttributeValue($key, $value)
{
if (empty($value) || ($this->getTranslator() === null)) {
return $value;
}
if (isset($this->translatableAttributes[$key]) || isset(self::$defaultTranslatableHtmlAttributes[$key])) {
return $this->getTranslator()->translate($value, $this->getTranslatorTextDomain());
} else {
foreach ($this->translatableAttributePrefixes as $prefix) {
if (0 === mb_strpos($key, $prefix)) {
// prefix matches => return translated $value
return $this->getTranslator()->translate($value, $this->getTranslatorTextDomain());
}
}
foreach (self::$defaultTranslatableHtmlAttributePrefixes as $prefix) {
if (0 === mb_strpos($key, $prefix)) {
// default prefix matches => return translated $value
return $this->getTranslator()->translate($value, $this->getTranslatorTextDomain());
}
}
}
return $value;
}
/**
* Adds an HTML attribute to the list of valid attributes
*
* @param string $attribute
* @return AbstractHelper
* @throws InvalidArgumentException for attribute names that are invalid
* per the HTML specifications.
*/
public function addValidAttribute($attribute)
{
if (! $this->isValidAttributeName($attribute)) {
throw new InvalidArgumentException(sprintf('%s is not a valid attribute name', $attribute));
}
$this->validTagAttributes[$attribute] = true;
return $this;
}
/**
* Adds a prefix to the list of valid attribute prefixes
*
* @param string $prefix
* @return AbstractHelper
* @throws InvalidArgumentException for attribute prefixes that are invalid
* per the HTML specifications for attribute names.
*/
public function addValidAttributePrefix($prefix)
{
if (! $this->isValidAttributeName($prefix)) {
throw new InvalidArgumentException(sprintf('%s is not a valid attribute prefix', $prefix));
}
$this->validTagAttributePrefixes[] = $prefix;
return $this;
}
/**
* Adds an HTML attribute to the list of translatable attributes
*
* @param string $attribute
*
* @return AbstractHelper
*/
public function addTranslatableAttribute($attribute)
{
$this->translatableAttributes[$attribute] = true;
return $this;
}
/**
* Adds an HTML attribute to the list of the default translatable attributes
*
* @param string $attribute
*/
public static function addDefaultTranslatableAttribute($attribute)
{
self::$defaultTranslatableHtmlAttributes[$attribute] = true;
}
/**
* Adds an HTML attribute to the list of translatable attributes
*
* @param string $prefix
*
* @return AbstractHelper
*/
public function addTranslatableAttributePrefix($prefix)
{
$this->translatableAttributePrefixes[] = $prefix;
return $this;
}
/**
* Adds an HTML attribute to the list of translatable attributes
*
* @param string $prefix
*/
public static function addDefaultTranslatableAttributePrefix($prefix)
{
self::$defaultTranslatableHtmlAttributePrefixes[] = $prefix;
}
/**
* Whether the passed attribute is valid or not
*
* @see https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
* Description of valid attributes
* @param string $attribute
* @return bool
*/
protected function isValidAttributeName($attribute)
{
return preg_match('/^[^\t\n\f \/>"\'=]+$/', $attribute);
}
/**
* Whether the passed attribute has a valid prefix or not
*
* @param string $attribute
* @return bool
*/
protected function hasAllowedPrefix($attribute)
{
foreach ($this->validTagAttributePrefixes as $prefix) {
if (str_starts_with($attribute, $prefix)) {
return true;
}
}
return false;
}
}
================================================
FILE: src/Zend/Form/src/View/Helper/Captcha/AbstractWord.php
================================================
render($element);
}
/**
* Render captcha form elements for the given element
*
* Creates and returns:
* - Hidden input with captcha identifier (name[id])
* - Text input for entering captcha value (name[input])
*
* More specific renderers will consume this and render it.
*
* @param ElementInterface $element
* @throws Exception\DomainException
* @return string
*/
protected function renderCaptchaInputs(ElementInterface $element)
{
$name = $element->getName();
if ($name === null || $name === '') {
throw new Exception\DomainException(sprintf(
'%s requires that the element has an assigned name; none discovered',
__METHOD__
));
}
$attributes = $element->getAttributes();
$captcha = $element->getCaptcha();
if ($captcha === null || ! $captcha instanceof CaptchaAdapter) {
throw new Exception\DomainException(sprintf(
'%s requires that the element has a "captcha" attribute implementing Zend\Captcha\AdapterInterface; '
. 'none found',
__METHOD__
));
}
$hidden = $this->renderCaptchaHidden($captcha, $attributes);
$input = $this->renderCaptchaInput($attributes);
return $hidden . $input;
}
/**
* Render the hidden input with the captcha identifier
*
* @param CaptchaAdapter $captcha
* @param array $attributes
* @return string
*/
protected function renderCaptchaHidden(CaptchaAdapter $captcha, array $attributes)
{
$attributes['type'] = 'hidden';
$attributes['name'] .= '[id]';
if (isset($attributes['id'])) {
$attributes['id'] .= '-hidden';
}
if (method_exists($captcha, 'getId')) {
$attributes['value'] = $captcha->getId();
} elseif (array_key_exists('value', $attributes)) {
if (is_array($attributes['value']) && array_key_exists('id', $attributes['value'])) {
$attributes['value'] = $attributes['value']['id'];
}
}
$closingBracket = $this->getInlineClosingBracket();
$hidden = sprintf(
'createAttributesString($attributes),
$closingBracket
);
return $hidden;
}
/**
* Render the input for capturing the captcha value from the client
*
* @param array $attributes
* @return string
*/
protected function renderCaptchaInput(array $attributes)
{
$attributes['type'] = 'text';
$attributes['name'] .= '[input]';
if (array_key_exists('value', $attributes)) {
unset($attributes['value']);
}
$closingBracket = $this->getInlineClosingBracket();
$input = sprintf(
'createAttributesString($attributes),
$closingBracket
);
return $input;
}
/**
* Set value for captchaPosition
*
* @param mixed $captchaPosition
* @throws Exception\InvalidArgumentException
* @return AbstractWord
*/
public function setCaptchaPosition($captchaPosition)
{
$captchaPosition = strtolower($captchaPosition);
if (! in_array($captchaPosition, [self::CAPTCHA_APPEND, self::CAPTCHA_PREPEND])) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects either %s::CAPTCHA_APPEND or %s::CAPTCHA_PREPEND; received "%s"',
__METHOD__,
__CLASS__,
__CLASS__,
$captchaPosition
));
}
$this->captchaPosition = $captchaPosition;
return $this;
}
/**
* Get position of captcha
*
* @return string
*/
public function getCaptchaPosition()
{
return $this->captchaPosition;
}
/**
* Set separator string for captcha and inputs
*
* @param string $separator
* @return AbstractWord
*/
public function setSeparator($separator)
{
$this->separator = (string) $separator;
return $this;
}
/**
* Get separator for captcha and inputs
*
* @return string
*/
public function getSeparator()
{
return $this->separator;
}
}
================================================
FILE: src/Zend/Form/src/View/Helper/Captcha/Dumb.php
================================================
getCaptcha();
if ($captcha === null || ! $captcha instanceof CaptchaAdapter) {
throw new Exception\DomainException(sprintf(
'%s requires that the element has a "captcha" attribute of type Zend\Captcha\Dumb; none found',
__METHOD__
));
}
$captcha->generate();
$label = sprintf(
'%s %s',
$captcha->getLabel(),
strrev($captcha->getWord())
);
$position = $this->getCaptchaPosition();
$separator = $this->getSeparator();
$captchaInput = $this->renderCaptchaInputs($element);
$pattern = '%s%s%s';
if ($position === self::CAPTCHA_PREPEND) {
return sprintf($pattern, $captchaInput, $separator, $label);
}
return sprintf($pattern, $label, $separator, $captchaInput);
}
}
================================================
FILE: src/Zend/Form/src/View/Helper/Captcha/Figlet.php
================================================
getCaptcha();
if ($captcha === null || ! $captcha instanceof CaptchaAdapter) {
throw new Exception\DomainException(sprintf(
'%s requires that the element has a "captcha" attribute of type Zend\Captcha\Figlet; none found',
__METHOD__
));
}
$captcha->generate();
$figlet = sprintf(
'
%s
',
$captcha->getFiglet()->render($captcha->getWord())
);
$position = $this->getCaptchaPosition();
$separator = $this->getSeparator();
$captchaInput = $this->renderCaptchaInputs($element);
$pattern = '%s%s%s';
if ($position == self::CAPTCHA_PREPEND) {
return sprintf($pattern, $captchaInput, $separator, $figlet);
}
return sprintf($pattern, $figlet, $separator, $captchaInput);
}
}
================================================
FILE: src/Zend/Form/src/View/Helper/Captcha/Image.php
================================================
getCaptcha();
if ($captcha === null || ! $captcha instanceof CaptchaAdapter) {
throw new Exception\DomainException(sprintf(
'%s requires that the element has a "captcha" attribute of type Zend\Captcha\Image; none found',
__METHOD__
));
}
$captcha->generate();
$imgAttributes = [
'width' => $captcha->getWidth(),
'height' => $captcha->getHeight(),
'alt' => $captcha->getImgAlt(),
'src' => $captcha->getImgUrl() . $captcha->getId() . $captcha->getSuffix(),
];
if ($element->hasAttribute('id')) {
$imgAttributes['id'] = $element->getAttribute('id') . '-image';
}
$closingBracket = $this->getInlineClosingBracket();
$img = sprintf(
'createAttributesString($imgAttributes),
$closingBracket
);
$position = $this->getCaptchaPosition();
$separator = $this->getSeparator();
$captchaInput = $this->renderCaptchaInputs($element);
$pattern = '%s%s%s';
if ($position == self::CAPTCHA_PREPEND) {
return sprintf($pattern, $captchaInput, $separator, $img);
}
return sprintf($pattern, $img, $separator, $captchaInput);
}
}
================================================
FILE: src/Zend/Form/src/View/Helper/Captcha/ReCaptcha.php
================================================
render($element);
}
/**
* Render ReCaptcha form elements
*
* @param ElementInterface $element
* @throws Exception\DomainException
* @return string
*/
public function render(ElementInterface $element)
{
$element->getAttributes();
$captcha = $element->getCaptcha();
if ($captcha === null || ! $captcha instanceof CaptchaAdapter) {
throw new Exception\DomainException(sprintf(
'%s requires that the element has a "captcha" attribute implementing Zend\Captcha\AdapterInterface; '
. 'none found',
__METHOD__
));
}
$name = $element->getName();
$markup = $captcha->getService()->getHtml($name);
$hidden = $this->renderHiddenInput($name);
return $hidden . $markup;
}
/**
* Render hidden input element if the element's name is not 'g-recaptcha-response'
* so that required validation works
*
* Note that only the first parameter is needed, the other three parameters
* are deprecated.
*
* @param string $name
* @return string
*/
protected function renderHiddenInput($name)
{
if ($name === 'g-recaptcha-response') {
return '';
}
$pattern = 'getInlineClosingBracket();
$attributes = $this->createAttributesString([
'name' => $name,
'value' => 'g-recaptcha-response',
]);
$challenge = sprintf($pattern, $attributes, $closingBracket);
return $challenge;
}
/**
* No longer used with v2 of Recaptcha API
*
* @return string
* @deprecated
*
*/
protected function renderJsEvents()
{
return '';
}
}
================================================
FILE: src/Zend/Form/src/View/Helper/File/FormFileApcProgress.php
================================================
renderHiddenId();
}
/**
* Render a hidden form element with the progress id
*
* @return string
*/
public function renderHiddenId()
{
$attributes = [
'id' => 'progress_key',
'name' => $this->getName(),
'type' => 'hidden',
'value' => $this->getValue()
];
return sprintf(
'createAttributesString($attributes),
$this->getInlineClosingBracket()
);
}
/**
* @return string
*/
protected function getName()
{
return 'UPLOAD_IDENTIFIER';
}
/**
* @return string
*/
protected function getValue()
{
return uniqid();
}
}
================================================
FILE: src/Zend/Form/src/View/Helper/Form.php
================================================
true,
'action' => true,
'autocomplete' => true,
'enctype' => true,
'method' => true,
'name' => true,
'novalidate' => true,
'target' => true,
];
/**
* Invoke as function
*
* @param FormInterface|null $form
* @return Form|string
*/
public function __invoke(?FormInterface $form = null)
{
if (! $form) {
return $this;
}
return $this->render($form);
}
/**
* Render a form from the provided $form,
*
* @param FormInterface $form
* @return string
*/
public function render(FormInterface $form)
{
if (method_exists($form, 'prepare')) {
$form->prepare();
}
$formContent = '';
foreach ($form as $element) {
if ($element instanceof FieldsetInterface) {
$formContent .= $this->getView()->formCollection($element);
} else {
$formContent .= $this->getView()->formRow($element);
}
}
return $this->openTag($form) . $formContent . $this->closeTag();
}
/**
* Generate an opening form tag
*
* @param FormInterface|null $form
* @return string
*/
public function openTag(?FormInterface $form = null)
{
$doctype = $this->getDoctype();
$attributes = [];
if (! (Doctype::HTML5 === $doctype || Doctype::XHTML5 === $doctype)) {
$attributes = [
'action' => '',
'method' => 'get',
];
}
if ($form instanceof FormInterface) {
$formAttributes = $form->getAttributes();
if (! array_key_exists('id', $formAttributes) && array_key_exists('name', $formAttributes)) {
$formAttributes['id'] = $formAttributes['name'];
}
$attributes = array_merge($attributes, $formAttributes);
}
if ($attributes) {
return sprintf('';
}
}
================================================
FILE: src/Zend/Form/src/View/Helper/FormButton.php
================================================
true,
'autofocus' => true,
'disabled' => true,
'form' => true,
'formaction' => true,
'formenctype' => true,
'formmethod' => true,
'formnovalidate' => true,
'formtarget' => true,
'type' => true,
'value' => true,
];
/**
* Valid values for the button type
*
* @var array
*/
protected $validTypes = [
'button' => true,
'reset' => true,
'submit' => true,
];
/**
* Invoke helper as functor
*
* Proxies to {@link render()}.
*
* @param ElementInterface|null $element
* @param null|string $buttonContent
* @return string|FormButton
*/
public function __invoke(?ElementInterface $element = null, $buttonContent = null)
{
if (! $element) {
return $this;
}
return $this->render($element, $buttonContent);
}
/**
* Render a form