├── .github
└── FUNDING.yml
├── assets
├── screenshot-1.png
├── screenshot-2.gif
└── screenshot-3.gif
├── vendor
├── composer
│ ├── installed.json
│ ├── autoload_namespaces.php
│ ├── autoload_psr4.php
│ ├── autoload_classmap.php
│ ├── installed.php
│ ├── LICENSE
│ ├── autoload_static.php
│ ├── autoload_real.php
│ ├── InstalledVersions.php
│ └── ClassLoader.php
└── autoload.php
├── .config
└── rome.rjson
├── template
└── fields-daterange.html
├── composer.json
├── composer.lock
├── date-range-ninja-forms.php
├── js
├── date-setting-field.js
└── date-range.js
├── readme.txt
├── src
├── Field.php
└── DateRange.php
├── README.md
└── languages
└── date-range-ninja-forms.pot
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 | custom: https://paypal.me/PerSoderlind
3 |
4 |
--------------------------------------------------------------------------------
/assets/screenshot-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soderlind/date-range-ninja-forms/HEAD/assets/screenshot-1.png
--------------------------------------------------------------------------------
/assets/screenshot-2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soderlind/date-range-ninja-forms/HEAD/assets/screenshot-2.gif
--------------------------------------------------------------------------------
/assets/screenshot-3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soderlind/date-range-ninja-forms/HEAD/assets/screenshot-3.gif
--------------------------------------------------------------------------------
/vendor/composer/installed.json:
--------------------------------------------------------------------------------
1 | {
2 | "packages": [],
3 | "dev": true,
4 | "dev-package-names": []
5 | }
6 |
--------------------------------------------------------------------------------
/.config/rome.rjson:
--------------------------------------------------------------------------------
1 | // For configuration documentation see http://romefrontend.dev/#project-configuration
2 | name: "date-range-ninja-forms"
3 | root: true
4 |
--------------------------------------------------------------------------------
/vendor/autoload.php:
--------------------------------------------------------------------------------
1 | array($baseDir . '/src'),
10 | );
11 |
--------------------------------------------------------------------------------
/vendor/composer/autoload_classmap.php:
--------------------------------------------------------------------------------
1 | $vendorDir . '/composer/InstalledVersions.php',
10 | );
11 |
--------------------------------------------------------------------------------
/template/fields-daterange.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "soderlind/date-range-ninja-forms",
3 | "description": "Date Range field for Ninja Forms",
4 | "type": "wordpress-plugin",
5 | "homepage": "https://github.com/soderlind/date-range-ninja-forms",
6 | "license": [
7 | "GPL-2.0-only"
8 | ],
9 | "authors": [
10 | {
11 | "name": "Per Søderlind",
12 | "role": "Developer",
13 | "email": "per@soderlind.no",
14 | "homepage": "https://soderlind.no"
15 | }
16 | ],
17 | "autoload": {
18 | "psr-4": {
19 | "Soderlind\\NinjaForms\\DateRange\\": "src/"
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5 | "This file is @generated automatically"
6 | ],
7 | "content-hash": "f4158eb98d828e207a81c64117adc7e3",
8 | "packages": [],
9 | "packages-dev": [],
10 | "aliases": [],
11 | "minimum-stability": "stable",
12 | "stability-flags": [],
13 | "prefer-stable": false,
14 | "prefer-lowest": false,
15 | "platform": [],
16 | "platform-dev": [],
17 | "plugin-api-version": "2.0.0"
18 | }
19 |
--------------------------------------------------------------------------------
/vendor/composer/installed.php:
--------------------------------------------------------------------------------
1 |
3 | array (
4 | 'pretty_version' => 'dev-master',
5 | 'version' => 'dev-master',
6 | 'aliases' =>
7 | array (
8 | ),
9 | 'reference' => 'd6ec6ce6c5dd3f6ce168b30a985493f0275e5c56',
10 | 'name' => 'soderlind/date-range-ninja-forms',
11 | ),
12 | 'versions' =>
13 | array (
14 | 'soderlind/date-range-ninja-forms' =>
15 | array (
16 | 'pretty_version' => 'dev-master',
17 | 'version' => 'dev-master',
18 | 'aliases' =>
19 | array (
20 | ),
21 | 'reference' => 'd6ec6ce6c5dd3f6ce168b30a985493f0275e5c56',
22 | ),
23 | ),
24 | );
25 |
--------------------------------------------------------------------------------
/vendor/composer/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Copyright (c) Nils Adermann, Jordi Boggiano
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy
5 | of this software and associated documentation files (the "Software"), to deal
6 | in the Software without restriction, including without limitation the rights
7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the Software is furnished
9 | to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all
12 | copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | THE SOFTWARE.
21 |
22 |
--------------------------------------------------------------------------------
/vendor/composer/autoload_static.php:
--------------------------------------------------------------------------------
1 |
11 | array (
12 | 'Soderlind\\NinjaForms\\DateRange\\' => 31,
13 | ),
14 | );
15 |
16 | public static $prefixDirsPsr4 = array (
17 | 'Soderlind\\NinjaForms\\DateRange\\' =>
18 | array (
19 | 0 => __DIR__ . '/../..' . '/src',
20 | ),
21 | );
22 |
23 | public static $classMap = array (
24 | 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
25 | );
26 |
27 | public static function getInitializer(ClassLoader $loader)
28 | {
29 | return \Closure::bind(function () use ($loader) {
30 | $loader->prefixLengthsPsr4 = ComposerStaticInitc0a54d18667d05a61f5a4415561bb213::$prefixLengthsPsr4;
31 | $loader->prefixDirsPsr4 = ComposerStaticInitc0a54d18667d05a61f5a4415561bb213::$prefixDirsPsr4;
32 | $loader->classMap = ComposerStaticInitc0a54d18667d05a61f5a4415561bb213::$classMap;
33 |
34 | }, null, ClassLoader::class);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/date-range-ninja-forms.php:
--------------------------------------------------------------------------------
1 | {
10 | const nfRadio = Backbone.Radio; // rome-ignore lint/js/noUndeclaredVariables: Backbone is an external object.
11 |
12 | const DateRangeMinDateSettingChannel = nfRadio.channel("setting-min_date");
13 | const DateRangeMaxDateSettingChannel = nfRadio.channel("setting-max_date");
14 |
15 | const DateField = class extends Marionette.Object { // rome-ignore lint/js/noUndeclaredVariables: Marionett is an external object.
16 | nfTextboxStyle = {
17 | "background": "#f9f9f9",
18 | "border": "0",
19 | "marginTop": "7px",
20 | "padding": "12px 15px",
21 | "width": "100%",
22 | "height": "41px",
23 | };
24 | /**
25 | * initialize()
26 | *
27 | */
28 | initialize() {
29 | this.listenTo(
30 | DateRangeMinDateSettingChannel,
31 | "render:setting",
32 | this.renderDateField,
33 | );
34 | this.listenTo(
35 | DateRangeMaxDateSettingChannel,
36 | "render:setting",
37 | this.renderDateField,
38 | );
39 | }
40 |
41 | /**
42 | * Convert the textbox (input type="text") to date field (input type="date").
43 | *
44 | * - If empty, set the date to "today", in the format YYYY-MM-DD.
45 | * - Set the style of the field to the same as a textbox.
46 | *
47 | * @see https://caniuse.com/input-datetime
48 | *
49 | * @param {*} settingModel
50 | * @param {*} dataModel
51 | * @param {*} view
52 | */
53 | renderDateField(settingModel, dataModel, view) {
54 | const element = view.el.getElementsByClassName("setting")[0];
55 | element.attributes["type"].value = "date";
56 | element.attributes["pattern"] = "d{4}-d{2}-d{2}";
57 | Object.assign(element.style, this.nfTextboxStyle);
58 | }
59 | };
60 |
61 | new DateField();
62 | },
63 | );
64 |
--------------------------------------------------------------------------------
/vendor/composer/autoload_real.php:
--------------------------------------------------------------------------------
1 | = 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
30 | if ($useStaticLoader) {
31 | require __DIR__ . '/autoload_static.php';
32 |
33 | call_user_func(\Composer\Autoload\ComposerStaticInitc0a54d18667d05a61f5a4415561bb213::getInitializer($loader));
34 | } else {
35 | $map = require __DIR__ . '/autoload_namespaces.php';
36 | foreach ($map as $namespace => $path) {
37 | $loader->set($namespace, $path);
38 | }
39 |
40 | $map = require __DIR__ . '/autoload_psr4.php';
41 | foreach ($map as $namespace => $path) {
42 | $loader->setPsr4($namespace, $path);
43 | }
44 |
45 | $classMap = require __DIR__ . '/autoload_classmap.php';
46 | if ($classMap) {
47 | $loader->addClassMap($classMap);
48 | }
49 | }
50 |
51 | $loader->register(true);
52 |
53 | return $loader;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/readme.txt:
--------------------------------------------------------------------------------
1 | === Date Range for Ninja Forms ===
2 | Contributors: PerS
3 | Donate link: https://soderlind.no/donate/
4 | Tags: date
5 | Requires at least: 5.4
6 | Tested up to: 5.7
7 | Stable tag: trunk
8 | Requires PHP: 7.2
9 | License: GPLv2 or later
10 | License URI: https://www.gnu.org/licenses/gpl-2.0.html
11 |
12 | Add a Date Range field to Ninja Forms.
13 |
14 | == Description ==
15 |
16 | Add a Date Range field to your Ninja Forms.
17 |
18 | == Filters ==
19 |
20 | Add the filters to your child theme functions.php
21 |
22 | = `date_range_lang` =
23 |
24 | Override the value returned from get_locale().
25 |
26 | E.g. if using Polylang, add:
27 |
28 | `
29 | add_filter( 'date_range_lang', function( $locale ) {
30 | if ( function_exists( 'pll_current_language' ) ) {
31 | $locale = pll_current_language( 'locale' );
32 | }
33 | return $locale;
34 | } );
35 | `
36 |
37 | = `date_range_dropdowns` =
38 |
39 | Enable dropdowns for months, years.
40 |
41 | If `maxYear` is `null` then `maxYear` will be equal to `(new Date()).getFullYear()`.
42 |
43 | `
44 | add_filter( 'date_range_dropdowns', function( $dropdowns ) {
45 |
46 | $dropdowns = [
47 | 'minYear' => 2020,
48 | 'maxYear' => 2030,
49 | 'months' => false,
50 | 'years' => true, // show dropdown for years.
51 | ];
52 |
53 | return $dropdowns;
54 | } );
55 | `
56 |
57 | = `date_range_buttontext` =
58 |
59 | Text for buttons.
60 |
61 | `
62 | add_filter( 'date_range_buttontext', function( $buttontext ) {
63 |
64 | $buttontext = [
65 | 'apply' => 'Apply',
66 | 'cancel' => 'Cancel',
67 | 'previousMonth' => '',
68 | 'nextMonth' => '',
69 | ];
70 |
71 | return $buttontext;
72 | } );
73 | `
74 |
75 |
76 | == Installation ==
77 |
78 | 1. Upload the plugin files to the `/wp-content/plugins/data-range-ninja-forms` directory, or install the plugin through the WordPress plugins screen directly.
79 | 1. Activate the plugin through the 'Plugins' screen in WordPress
80 | 1. Use Ninja Forms to add the Date Range field.
81 |
82 | == Screenshots ==
83 |
84 | 1. Settings.
85 | 2. Using Ninja Forms to add the Date Range field.
86 | 3. Date Range at the front-end.
87 |
88 | == Changelog ==
89 |
90 | = 1.1.0 =
91 |
92 | * Update to latest version of [Litepicker](https://github.com/wakirin/Litepicker)
93 |
94 | = 1.0.2 =
95 |
96 | * Lint source code using PHP CodeSniffer and [Rome](https://rome.tools/).
97 |
98 | = 1.0.1 =
99 |
100 | * Add date setting field.
101 |
102 | = 1.0.0 =
103 |
104 | * Refactor
105 |
106 | = 0.0.7 =
107 |
108 | * Refactor JavaScript to ES6.
109 |
110 | = 0.0.6 =
111 |
112 | * Fix breaking bug
113 |
114 | = 0.0.5 =
115 |
116 | * Add more settings.
117 | * Add [filters](#filters): `date_range_lang`, `date_range_dropdowns` and `date_range_buttontext`.
118 | * Add `languages/date-range-ninja-forms.pot`
119 |
120 | = 0.0.4 =
121 |
122 | * Replace Lightpick, no longer maintained, with [Litepicker](https://github.com/wakirin/Litepicker)
123 |
124 | = 0.0.3 =
125 |
126 | * In Ninja Forms builder, select WP Settings date.
127 |
128 | = 0.0.2 =
129 |
130 | * Set date format in Ninja Form builder
131 |
132 | = 0.0.1 =
133 |
134 | * Initial release.
135 |
136 |
137 |
--------------------------------------------------------------------------------
/src/Field.php:
--------------------------------------------------------------------------------
1 | _nicename = __( 'Date Range', 'date-range-ninja-forms' );
112 | $this->init();
113 | }
114 |
115 |
116 | /**
117 | * Process the field.
118 | *
119 | * @param array $field Fields.
120 | * @param array $data Data.
121 | * @return array
122 | */
123 | public function process( $field, $data ) {
124 | return $data;
125 | }
126 |
127 | /**
128 | * Init.
129 | *
130 | * @return void
131 | */
132 | public function init() {
133 | add_filter( 'ninja_forms_field_template_file_paths', [ $this, 'register_template_path' ] );
134 | add_action( 'ninja_forms_enqueue_scripts', [ $this, 'scripts' ] );
135 | add_action( 'init', [ $this, 'load_textdomain' ] );
136 | }
137 |
138 | /**
139 | * Register the template path for the plugin
140 | *
141 | * @param array $file_paths Template paths.
142 | *
143 | * @return array
144 | */
145 | public function register_template_path( $file_paths ) {
146 | $file_paths[] = plugin_dir_path( DATERANGE_FILE ) . 'template/';
147 | return $file_paths;
148 | }
149 |
150 | /**
151 | * Enqueue scripts
152 | *
153 | * The js/date-range.js file connects the Litepicker script with ninja forms.
154 | *
155 | * @return void
156 | */
157 | public function scripts() {
158 | wp_enqueue_script( 'dayjs', '//cdnjs.cloudflare.com/ajax/libs/dayjs/1.8.35/dayjs.min.js', [], DATERANGE_VERSION, true );
159 | wp_enqueue_script( 'lightpicker', '//cdn.jsdelivr.net/npm/litepicker/dist/litepicker.js', [ 'dayjs' ], DATERANGE_VERSION, true );
160 | wp_enqueue_script( 'date-range', plugin_dir_url( DATERANGE_FILE ) . 'js/date-range.js', [ 'lightpicker' ], DATERANGE_VERSION, true );
161 | wp_localize_script(
162 | 'date-range',
163 | 'drDateRange',
164 | [
165 | 'dateFormat' => get_option( 'date_format' ),
166 | 'lang' => apply_filters( 'date_range_lang', get_locale() ),
167 | 'dropdowns' => apply_filters( 'date_range_dropdowns', wp_json_encode( [] ) ),
168 | 'buttontext' => apply_filters( 'date_range_buttontext', wp_json_encode( [] ) ),
169 | ]
170 | );
171 | }
172 |
173 | /**
174 | * Load translation.
175 | *
176 | * @return void
177 | */
178 | public function load_textdomain() {
179 | load_plugin_textdomain( 'date-range-ninja-forms', false, dirname( plugin_basename( DATERANGE_FILE ) ) . '/languages' );
180 | }
181 | }
182 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Date Range field for Ninja Forms
2 |
3 | [](//packagist.org/packages/soderlind/date-range-ninja-forms)
4 |
5 |
6 | [Description](#description) | [Installation](#installation) | [Screenshots](#screenshots) | [Filters](#filters) | [Changelog](#changelog) | [Credits](#credits) | [Copyright and License](#copyright-and-license)
7 |
8 |
9 | ## Description
10 |
11 | Add a Date Range field to your Ninja Forms.
12 |
13 |
14 | ## Installation
15 |
16 | 1. Upload the plugin files to the `/wp-content/plugins/data-range-ninja-forms` directory, or install the plugin through the WordPress plugins screen directly.
17 | 1. Activate the plugin through the 'Plugins' screen in WordPress
18 | 1. Use Ninja Forms to add the Date Range field.
19 |
20 |
21 | ## Screenshots
22 |
23 | ### 1. Settings
24 |
25 |
26 | ### 2. Using Ninja Forms to add the Date Range field.
27 |
28 |
29 | ### 3. Date Range at the front-end.
30 |
31 |
32 | ## Filters
33 |
34 | Add the filters to your child theme functions.php
35 |
36 | ### `date_range_lang`
37 |
38 | Override the value returned from get_locale().
39 |
40 | E.g. if using Polylang, add:
41 |
42 | ```php
43 | add_filter( 'date_range_lang', function( $locale ) {
44 | if ( function_exists( 'pll_current_language' ) ) {
45 | $locale = pll_current_language( 'locale' );
46 | }
47 | return $locale;
48 | } );
49 | ```
50 |
51 | ### `date_range_dropdowns`
52 |
53 | Enable dropdowns for months, years.
54 |
55 | If `maxYear` is `null` then `maxYear` will be equal to `(new Date()).getFullYear()`.
56 |
57 | ```php
58 | add_filter( 'date_range_dropdowns', function( $dropdowns ) {
59 |
60 | $dropdowns = [
61 | 'minYear' => 2020,
62 | 'maxYear' => 2030,
63 | 'months' => false,
64 | 'years' => true, // show dropdown for years.
65 | ];
66 |
67 | return $dropdowns;
68 | } );
69 | ```
70 |
71 | ### `date_range_buttontext`
72 |
73 | Text for buttons.
74 |
75 | ```php
76 | add_filter( 'date_range_buttontext', function( $buttontext ) {
77 |
78 | $buttontext = [
79 | 'apply' => 'Apply',
80 | 'cancel' => 'Cancel',
81 | 'previousMonth' => '',
82 | 'nextMonth' => '',
83 | ];
84 |
85 | return $buttontext;
86 | } );
87 | ```
88 |
89 | ## See also
90 |
91 | I've created an [iCalendar](https://github.com/soderlind/icalendar-ninja-form) add-on for Ninja Forms.
92 |
93 | ## Changelog
94 |
95 | ### 1.1.0
96 |
97 | - Update to latest version of [Litepicker](https://github.com/wakirin/Litepicker)
98 |
99 | ### 1.0.2
100 |
101 | - Lint source code using PHP CodeSniffer and [Rome](https://rome.tools/).
102 |
103 | ### 1.0.1
104 |
105 | - Add date setting field
106 |
107 | ### 1.0.0
108 |
109 | - Refactor
110 |
111 | ### 0.1.0
112 |
113 | - [Custom validation](https://github.com/soderlind/date-range-ninja-forms/blob/master/js/date-range.js#L29-L106) for required fields
114 | - Add moment.js
115 | - Refactor code, using ES2019 Class Fields.
116 |
117 | ### 0.0.7
118 |
119 | - Refactor JavaScript to ES6.
120 |
121 | ### 0.0.6
122 |
123 | - Fix breaking bug
124 |
125 | ### 0.0.5
126 |
127 | - Add more settings.
128 | - Add [filters](#filters): `date_range_lang`, `date_range_dropdowns` and `date_range_buttontext`.
129 | - Add `languages/date-range-ninja-forms.pot`
130 |
131 |
132 | ### 0.0.4
133 |
134 | - Replace Lightpick, no longer maintained, with [Litepicker](https://github.com/wakirin/Litepicker)
135 |
136 |
137 | ### 0.0.3
138 |
139 | - In Ninja Forms builder, select WP Settings date.
140 |
141 | ### 0.0.2
142 |
143 | - Set date format in Ninja Form builder
144 |
145 | ### 0.0.1
146 |
147 | - Initial release.
148 |
149 |
150 | ## Credits
151 |
152 | Date Range field for Ninja Forms uses [Litepicker](https://github.com/wakirin/Litepicker). The Litepicker has a MIT licence and is Copyright 2019 [Rinat G](https://github.com/wakirin/).
153 |
154 | ## Copyright and License
155 |
156 | Date Range field for Ninja Forms is copyright 2020 Per Soderlind
157 |
158 | Date Range field for Ninja Forms is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version.
159 |
160 | Date Range field for Ninja Forms is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
161 |
162 | You should have received a copy of the GNU Lesser General Public License along with the Extension. If not, see http://www.gnu.org/licenses/.
163 |
--------------------------------------------------------------------------------
/languages/date-range-ninja-forms.pot:
--------------------------------------------------------------------------------
1 | #, fuzzy
2 | msgid ""
3 | msgstr ""
4 | "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
5 | "Project-Id-Version: Date Range field for Ninja Forms\n"
6 | "POT-Creation-Date: 2020-03-05 00:13+0100\n"
7 | "PO-Revision-Date: 2020-03-04 10:46+0100\n"
8 | "Last-Translator: \n"
9 | "Language-Team: \n"
10 | "MIME-Version: 1.0\n"
11 | "Content-Type: text/plain; charset=UTF-8\n"
12 | "Content-Transfer-Encoding: 8bit\n"
13 | "X-Generator: Poedit 2.3\n"
14 | "X-Poedit-Basepath: ..\n"
15 | "X-Poedit-Flags-xgettext: --add-comments=translators:\n"
16 | "X-Poedit-WPHeader: date-range-ninja-forms.php\n"
17 | "X-Poedit-SourceCharset: UTF-8\n"
18 | "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;"
19 | "esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;"
20 | "_n_noop:1,2;_nx_noop:3c,1,2;__ngettext_noop:1,2\n"
21 | "X-Poedit-SearchPath-0: .\n"
22 | "X-Poedit-SearchPathExcluded-0: *.min.js\n"
23 |
24 | #: date-range-ninja-forms.php:75
25 | msgid "Date Range"
26 | msgstr ""
27 |
28 | #: date-range-ninja-forms.php:143
29 | msgid "Date Format"
30 | msgstr ""
31 |
32 | #: date-range-ninja-forms.php:148
33 | #, php-format
34 | msgid "WP Settings (%s)"
35 | msgstr ""
36 |
37 | #: date-range-ninja-forms.php:198
38 | msgid "Start of Week"
39 | msgstr ""
40 |
41 | #: date-range-ninja-forms.php:203
42 | msgid "Sunday"
43 | msgstr ""
44 |
45 | #: date-range-ninja-forms.php:207
46 | msgid "Monday"
47 | msgstr ""
48 |
49 | #: date-range-ninja-forms.php:211
50 | msgid "Tuesday"
51 | msgstr ""
52 |
53 | #: date-range-ninja-forms.php:215
54 | msgid "Wednesday"
55 | msgstr ""
56 |
57 | #: date-range-ninja-forms.php:219
58 | msgid "Thursday"
59 | msgstr ""
60 |
61 | #: date-range-ninja-forms.php:223
62 | msgid "Friday"
63 | msgstr ""
64 |
65 | #: date-range-ninja-forms.php:227
66 | msgid "Saturday"
67 | msgstr ""
68 |
69 | #: date-range-ninja-forms.php:245
70 | msgid "Show Tool Tip"
71 | msgstr ""
72 |
73 | #: date-range-ninja-forms.php:254
74 | msgid "Singular"
75 | msgstr ""
76 |
77 | #: date-range-ninja-forms.php:266
78 | msgid "Plural"
79 | msgstr ""
80 |
81 | #: date-range-ninja-forms.php:279
82 | msgid "Tooltip"
83 | msgstr ""
84 |
85 | #: date-range-ninja-forms.php:288
86 | msgid "Limit Range"
87 | msgstr ""
88 |
89 | #: date-range-ninja-forms.php:297
90 | msgid "Start Date"
91 | msgstr ""
92 |
93 | #: date-range-ninja-forms.php:298
94 | msgid "The minimum/earliest date that can be selected."
95 | msgstr ""
96 |
97 | #: date-range-ninja-forms.php:310
98 | msgid "End Date"
99 | msgstr ""
100 |
101 | #: date-range-ninja-forms.php:311
102 | msgid ""
103 | "The maximum/latest date that can be selected. Leave blank if indefinite."
104 | msgstr ""
105 |
106 | #: date-range-ninja-forms.php:324
107 | msgid "Set Min / Max Days"
108 | msgstr ""
109 |
110 | #: date-range-ninja-forms.php:334
111 | msgid "Minimum days"
112 | msgstr ""
113 |
114 | #: date-range-ninja-forms.php:335
115 | msgid "The minimum days of the selected range."
116 | msgstr ""
117 |
118 | #: date-range-ninja-forms.php:346
119 | msgid "Maximum Days"
120 | msgstr ""
121 |
122 | #: date-range-ninja-forms.php:347
123 | msgid "The maximum days of the selected range."
124 | msgstr ""
125 |
126 | #: date-range-ninja-forms.php:359
127 | msgid "Control date range"
128 | msgstr ""
129 |
130 | #: date-range-ninja-forms.php:368
131 | msgid "Number of days"
132 | msgstr ""
133 |
134 | #: date-range-ninja-forms.php:377
135 | msgid "Show Week Numbers"
136 | msgstr ""
137 |
138 | #: date-range-ninja-forms.php:386
139 | msgid "Disable Weekends"
140 | msgstr ""
141 |
142 | #: date-range-ninja-forms.php:395
143 | msgid "Select Backward"
144 | msgstr ""
145 |
146 | #: date-range-ninja-forms.php:396
147 | msgid "Select second date before the first selected date."
148 | msgstr ""
149 |
150 | #: date-range-ninja-forms.php:405
151 | msgid "Select Forward"
152 | msgstr ""
153 |
154 | #: date-range-ninja-forms.php:406
155 | msgid "Select second date after the first selected date."
156 | msgstr ""
157 |
158 | #: date-range-ninja-forms.php:415
159 | msgid "Auto Apply"
160 | msgstr ""
161 |
162 | #: date-range-ninja-forms.php:416
163 | msgid ""
164 | "When enabled, hide the apply and cancel buttons, and automatically apply a "
165 | "new date range as soon as two dates are clicked."
166 | msgstr ""
167 |
168 | #. Plugin Name of the plugin/theme
169 | msgid "Date Range field for Ninja Forms"
170 | msgstr ""
171 |
172 | #. Plugin URI of the plugin/theme
173 | msgid "https://github.com/soderlind/date-range-ninja-forms"
174 | msgstr ""
175 |
176 | #. Description of the plugin/theme
177 | msgid "Add a Date Range field to your Ninja Forms."
178 | msgstr ""
179 |
180 | #. Author of the plugin/theme
181 | msgid "Per Soderlind"
182 | msgstr ""
183 |
184 | #. Author URI of the plugin/theme
185 | msgid "https://soderlind.no"
186 | msgstr ""
187 |
--------------------------------------------------------------------------------
/vendor/composer/InstalledVersions.php:
--------------------------------------------------------------------------------
1 |
27 | array (
28 | 'pretty_version' => 'dev-master',
29 | 'version' => 'dev-master',
30 | 'aliases' =>
31 | array (
32 | ),
33 | 'reference' => 'd6ec6ce6c5dd3f6ce168b30a985493f0275e5c56',
34 | 'name' => 'soderlind/date-range-ninja-forms',
35 | ),
36 | 'versions' =>
37 | array (
38 | 'soderlind/date-range-ninja-forms' =>
39 | array (
40 | 'pretty_version' => 'dev-master',
41 | 'version' => 'dev-master',
42 | 'aliases' =>
43 | array (
44 | ),
45 | 'reference' => 'd6ec6ce6c5dd3f6ce168b30a985493f0275e5c56',
46 | ),
47 | ),
48 | );
49 | private static $canGetVendors;
50 | private static $installedByVendor = array();
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | public static function getInstalledPackages()
59 | {
60 | $packages = array();
61 | foreach (self::getInstalled() as $installed) {
62 | $packages[] = array_keys($installed['versions']);
63 | }
64 |
65 |
66 | if (1 === \count($packages)) {
67 | return $packages[0];
68 | }
69 |
70 | return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
71 | }
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 | public static function isInstalled($packageName)
82 | {
83 | foreach (self::getInstalled() as $installed) {
84 | if (isset($installed['versions'][$packageName])) {
85 | return true;
86 | }
87 | }
88 |
89 | return false;
90 | }
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 | public static function satisfies(VersionParser $parser, $packageName, $constraint)
106 | {
107 | $constraint = $parser->parseConstraints($constraint);
108 | $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
109 |
110 | return $provided->matches($constraint);
111 | }
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 | public static function getVersionRanges($packageName)
123 | {
124 | foreach (self::getInstalled() as $installed) {
125 | if (!isset($installed['versions'][$packageName])) {
126 | continue;
127 | }
128 |
129 | $ranges = array();
130 | if (isset($installed['versions'][$packageName]['pretty_version'])) {
131 | $ranges[] = $installed['versions'][$packageName]['pretty_version'];
132 | }
133 | if (array_key_exists('aliases', $installed['versions'][$packageName])) {
134 | $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
135 | }
136 | if (array_key_exists('replaced', $installed['versions'][$packageName])) {
137 | $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
138 | }
139 | if (array_key_exists('provided', $installed['versions'][$packageName])) {
140 | $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
141 | }
142 |
143 | return implode(' || ', $ranges);
144 | }
145 |
146 | throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
147 | }
148 |
149 |
150 |
151 |
152 |
153 | public static function getVersion($packageName)
154 | {
155 | foreach (self::getInstalled() as $installed) {
156 | if (!isset($installed['versions'][$packageName])) {
157 | continue;
158 | }
159 |
160 | if (!isset($installed['versions'][$packageName]['version'])) {
161 | return null;
162 | }
163 |
164 | return $installed['versions'][$packageName]['version'];
165 | }
166 |
167 | throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
168 | }
169 |
170 |
171 |
172 |
173 |
174 | public static function getPrettyVersion($packageName)
175 | {
176 | foreach (self::getInstalled() as $installed) {
177 | if (!isset($installed['versions'][$packageName])) {
178 | continue;
179 | }
180 |
181 | if (!isset($installed['versions'][$packageName]['pretty_version'])) {
182 | return null;
183 | }
184 |
185 | return $installed['versions'][$packageName]['pretty_version'];
186 | }
187 |
188 | throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
189 | }
190 |
191 |
192 |
193 |
194 |
195 | public static function getReference($packageName)
196 | {
197 | foreach (self::getInstalled() as $installed) {
198 | if (!isset($installed['versions'][$packageName])) {
199 | continue;
200 | }
201 |
202 | if (!isset($installed['versions'][$packageName]['reference'])) {
203 | return null;
204 | }
205 |
206 | return $installed['versions'][$packageName]['reference'];
207 | }
208 |
209 | throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
210 | }
211 |
212 |
213 |
214 |
215 |
216 | public static function getRootPackage()
217 | {
218 | $installed = self::getInstalled();
219 |
220 | return $installed[0]['root'];
221 | }
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 | public static function getRawData()
230 | {
231 | return self::$installed;
232 | }
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 | public static function reload($data)
253 | {
254 | self::$installed = $data;
255 | self::$installedByVendor = array();
256 | }
257 |
258 |
259 |
260 |
261 | private static function getInstalled()
262 | {
263 | if (null === self::$canGetVendors) {
264 | self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
265 | }
266 |
267 | $installed = array();
268 |
269 | if (self::$canGetVendors) {
270 | foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
271 | if (isset(self::$installedByVendor[$vendorDir])) {
272 | $installed[] = self::$installedByVendor[$vendorDir];
273 | } elseif (is_file($vendorDir.'/composer/installed.php')) {
274 | $installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
275 | }
276 | }
277 | }
278 |
279 | $installed[] = self::$installed;
280 |
281 | return $installed;
282 | }
283 | }
284 |
--------------------------------------------------------------------------------
/src/DateRange.php:
--------------------------------------------------------------------------------
1 | init();
36 | }
37 | return self::$instance;
38 | }
39 |
40 | /**
41 | * Add hooks.
42 | *
43 | * @return void
44 | */
45 | public function init() {
46 | add_filter( 'ninja_forms_register_fields', [ $this, 'register_fields' ] );
47 | add_filter( 'ninja_forms_field_settings', [ $this, 'field_settings' ] );
48 | add_action( 'nf_admin_enqueue_scripts', [ $this, 'admin_scripts' ] );
49 | }
50 |
51 | /**
52 | * Register Date Range field
53 | *
54 | * @param array $fields All fields.
55 | *
56 | * @return array
57 | */
58 | public function register_fields( $fields ) {
59 | $fields['daterange'] = new Field();
60 |
61 | return $fields;
62 | }
63 |
64 | /**
65 | * Add field settings.
66 | *
67 | * @param array $settings All setings.
68 | *
69 | * @return array
70 | */
71 | public function field_settings( $settings ) {
72 |
73 | $settings['date_format'] = [
74 | 'name' => 'date_format',
75 | 'type' => 'select',
76 | 'label' => __( 'Date Format', 'date-range-ninja-forms' ),
77 | 'width' => 'one-half',
78 | 'group' => 'primary',
79 | 'options' => [
80 | [
81 | /* translators: Get the date from WordPress settings. */
82 | 'label' => sprintf( __( 'WP Settings (%s)', 'date-range-ninja-forms' ), get_option( 'date_format' ) ),
83 | 'value' => 'default',
84 | ],
85 | [
86 | 'label' => 'm/d/Y',
87 | 'value' => 'MM/DD/YYYY',
88 | ],
89 | [
90 | 'label' => 'm-d-Y',
91 | 'value' => 'MM-DD-YYYY',
92 | ],
93 | [
94 | 'label' => 'm.d.Y',
95 | 'value' => 'MM.DD.YYYY',
96 | ],
97 | [
98 | 'label' => 'd/m/Y',
99 | 'value' => 'DD/MM/YYYY',
100 | ],
101 | [
102 | 'label' => 'd-m-Y',
103 | 'value' => 'DD-MM-YYYY',
104 | ],
105 | [
106 | 'label' => 'd.m.Y',
107 | 'value' => 'DD.MM.YYYY',
108 | ],
109 | [
110 | 'label' => 'Y-m-d',
111 | 'value' => 'YYYY-MM-DD',
112 | ],
113 | [
114 | 'label' => 'Y/m/d',
115 | 'value' => 'YYYY/MM/DD',
116 | ],
117 | [
118 | 'label' => 'Y.m.d',
119 | 'value' => 'YYYY.MM.DD',
120 | ],
121 | [
122 | 'label' => 'l, F d Y',
123 | 'value' => 'dddd, MMMM D YYYY',
124 | ],
125 | ],
126 | 'value' => 'default', // the initial selected value.
127 | ];
128 |
129 | $settings['start_of_week'] = [
130 | 'name' => 'start_of_week',
131 | 'type' => 'select',
132 | 'label' => __( 'Start of Week', 'date-range-ninja-forms' ),
133 | 'width' => 'one-half',
134 | 'group' => 'primary',
135 | 'options' => [
136 | [
137 | 'label' => __( 'Sunday', 'date-range-ninja-forms' ),
138 | 'value' => '0',
139 | ],
140 | [
141 | 'label' => __( 'Monday', 'date-range-ninja-forms' ),
142 | 'value' => '1',
143 | ],
144 | [
145 | 'label' => __( 'Tuesday', 'date-range-ninja-forms' ),
146 | 'value' => '2',
147 | ],
148 | [
149 | 'label' => __( 'Wednesday', 'date-range-ninja-forms' ),
150 | 'value' => '3',
151 | ],
152 | [
153 | 'label' => __( 'Thursday', 'date-range-ninja-forms' ),
154 | 'value' => '4',
155 | ],
156 | [
157 | 'label' => __( 'Friday', 'date-range-ninja-forms' ),
158 | 'value' => '5',
159 | ],
160 | [
161 | 'label' => __( 'Saturday', 'date-range-ninja-forms' ),
162 | 'value' => '6',
163 | ],
164 | ],
165 | 'value' => get_option( 'start_of_week' ), // the initial selected value.
166 | ];
167 |
168 | /*
169 | |--------------------------------------------------------------------------
170 | | Advanced Settings
171 | |--------------------------------------------------------------------------
172 | |
173 | | The least commonly used settings for a field.
174 | */
175 |
176 | $tooltip['tooltip'] = [
177 | 'name' => 'tooltip',
178 | 'type' => 'toggle',
179 | 'label' => esc_html__( 'Show Tool Tip', 'date-range-ninja-forms' ),
180 | 'width' => 'one-third',
181 | 'group' => 'advanced',
182 | 'value' => false,
183 | ];
184 |
185 | $tooltip['tooltip_singular'] = [
186 | 'name' => 'tooltip_singular',
187 | 'type' => 'textbox',
188 | 'label' => esc_html__( 'Singular', 'date-range-ninja-forms' ),
189 | 'width' => 'one-third',
190 | 'group' => 'advanced',
191 | 'value' => 'day',
192 | 'deps' => [
193 | 'tooltip' => 1,
194 | ],
195 | ];
196 |
197 | $tooltip['tooltip_plural'] = [
198 | 'name' => 'tooltip_plural',
199 | 'type' => 'textbox',
200 | 'label' => esc_html__( 'Plural', 'date-range-ninja-forms' ),
201 | 'width' => 'one-third',
202 | 'group' => 'advanced',
203 | 'value' => 'days',
204 | 'deps' => [
205 | 'tooltip' => 1,
206 | ],
207 | ];
208 |
209 | $settings['tooltip_fieldset'] = [
210 | 'name' => 'tooltip_fieldset',
211 | 'type' => 'fieldset',
212 | 'label' => esc_html__( 'Tooltip', 'date-range-ninja-forms' ),
213 | 'width' => 'full',
214 | 'group' => 'advanced',
215 | 'settings' => $tooltip,
216 | ];
217 |
218 | $start_end['max_min_date'] = [
219 | 'name' => 'max_min_date',
220 | 'type' => 'toggle',
221 | 'label' => esc_html__( 'Limit Range', 'date-range-ninja-forms' ),
222 | 'width' => 'one-third',
223 | 'group' => 'advanced',
224 | 'value' => 0,
225 | ];
226 |
227 | $start_end['min_date'] = [
228 | 'name' => 'min_date',
229 | 'type' => 'textbox',
230 | 'label' => esc_html__( 'Start Date', 'date-range-ninja-forms' ),
231 | 'help' => esc_html__( 'The minimum/earliest date that can be selected.', 'date-range-ninja-forms' ),
232 | 'placeholder' => 'YYYY-MM-DD',
233 | 'width' => 'one-third',
234 | 'group' => 'advanced',
235 | 'value' => '',
236 | 'deps' => [
237 | 'max_min_date' => 1,
238 | ],
239 | ];
240 | $start_end['max_date'] = [
241 | 'name' => 'max_date',
242 | 'type' => 'textbox',
243 | 'label' => esc_html__( 'End Date', 'date-range-ninja-forms' ),
244 | 'help' => esc_html__( 'The maximum/latest date that can be selected. Leave blank if indefinite.', 'date-range-ninja-forms' ),
245 | 'placeholder' => 'YYYY-MM-DD',
246 | 'width' => 'one-third',
247 | 'group' => 'advanced',
248 | 'value' => '',
249 | 'deps' => [
250 | 'max_min_date' => 1,
251 | ],
252 | ];
253 |
254 | $min_max['min_max_days'] = [
255 | 'name' => 'min_max_days',
256 | 'type' => 'toggle',
257 | 'label' => esc_html__( 'Set Min / Max Days', 'date-range-ninja-forms' ),
258 | 'width' => 'one-third',
259 | 'group' => 'advanced',
260 | 'value' => 0,
261 | ];
262 |
263 | $min_max['min_days'] = [
264 | 'name' => 'min_days',
265 | 'type' => 'number',
266 | 'label' => esc_html__( 'Minimum days', 'date-range-ninja-forms' ),
267 | 'help' => esc_html__( 'The minimum days of the selected range.', 'date-range-ninja-forms' ),
268 | 'width' => 'one-third',
269 | 'group' => 'advanced',
270 | 'value' => '0',
271 | 'deps' => [
272 | 'min_max_days' => 1,
273 | ],
274 | ];
275 | $min_max['max_days'] = [
276 | 'name' => 'max_days',
277 | 'type' => 'number',
278 | 'label' => esc_html__( 'Maximum Days', 'date-range-ninja-forms' ),
279 | 'help' => esc_html__( 'The maximum days of the selected range.', 'date-range-ninja-forms' ),
280 | 'width' => 'one-third',
281 | 'group' => 'advanced',
282 | 'value' => '0',
283 | 'deps' => [
284 | 'min_max_days' => 1,
285 | ],
286 | ];
287 |
288 | $settings['max_min_date_fieldset'] = [
289 | 'name' => 'max_min_date_fieldset',
290 | 'type' => 'fieldset',
291 | 'label' => esc_html__( 'Control date range', 'date-range-ninja-forms' ),
292 | 'width' => 'full',
293 | 'group' => 'advanced',
294 | 'settings' => $start_end,
295 | ];
296 |
297 | $settings['min_max_days_fieldset'] = [
298 | 'name' => 'min_max_days_fieldset',
299 | 'type' => 'fieldset',
300 | 'label' => esc_html__( 'Number of days', 'date-range-ninja-forms' ),
301 | 'width' => 'full',
302 | 'group' => 'advanced',
303 | 'settings' => $min_max,
304 | ];
305 |
306 | $settings['show_week_numbers'] = [
307 | 'name' => 'show_week_numbers',
308 | 'type' => 'toggle',
309 | 'label' => esc_html__( 'Show Week Numbers', 'date-range-ninja-forms' ),
310 | 'width' => 'one-third',
311 | 'group' => 'advanced',
312 | 'value' => 0,
313 | ];
314 |
315 | $settings['disable_weekends'] = [
316 | 'name' => 'disable_weekends',
317 | 'type' => 'toggle',
318 | 'label' => esc_html__( 'Disable Weekends', 'date-range-ninja-forms' ),
319 | 'width' => 'one-third',
320 | 'group' => 'advanced',
321 | 'value' => 0,
322 | ];
323 |
324 | $settings['select_backward'] = [
325 | 'name' => 'select_backward',
326 | 'type' => 'toggle',
327 | 'label' => esc_html__( 'Select Backward', 'date-range-ninja-forms' ),
328 | 'help' => esc_html__( 'Select second date before the first selected date.', 'date-range-ninja-forms' ),
329 | 'width' => 'one-third',
330 | 'group' => 'advanced',
331 | 'value' => 0,
332 | ];
333 |
334 | $settings['select_forward'] = [
335 | 'name' => 'select_forward',
336 | 'type' => 'toggle',
337 | 'label' => esc_html__( 'Select Forward', 'date-range-ninja-forms' ),
338 | 'help' => esc_html__( 'Select second date after the first selected date.', 'date-range-ninja-forms' ),
339 | 'width' => 'one-third',
340 | 'group' => 'advanced',
341 | 'value' => 0,
342 | ];
343 |
344 | $settings['auto_apply'] = [
345 | 'name' => 'auto_apply',
346 | 'type' => 'toggle',
347 | 'label' => esc_html__( 'Auto Apply', 'date-range-ninja-forms' ),
348 | 'help' => esc_html__( 'When enabled, hide the apply and cancel buttons, and automatically apply a new date range as soon as two dates are clicked.', 'date-range-ninja-forms' ),
349 | 'width' => 'one-third',
350 | 'group' => 'advanced',
351 | 'value' => 1,
352 | ];
353 |
354 | return $settings;
355 | }
356 |
357 | /**
358 | * Enqueue setting field script.
359 | *
360 | * @return void
361 | */
362 | public function admin_scripts() {
363 | wp_enqueue_script( 'date-setting-field', plugin_dir_url( DATERANGE_FILE ) . 'js/date-setting-field.js', [], DATERANGE_VERSION, true );
364 | }
365 | }
366 |
--------------------------------------------------------------------------------
/js/date-range.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Thanks to https://ninjaformsdev.slack.com/archives/C0EFXJF0D/p1524614990000175
3 | */
4 | // @ts-check
5 | document.addEventListener(
6 | "DOMContentLoaded",
7 | () => {
8 | const nfRadio = Backbone.Radio;
9 | const radioChannel = nfRadio.channel("daterange"); // 'daterange', the $_type value, defined in date-range-ninja-forms.php
10 | const submitChannel = nfRadio.channel("submit");
11 | const fieldsChannel = nfRadio.channel("fields");
12 |
13 | const DateRange = class extends Marionette.Object {
14 | fieldType = "daterange";
15 | fieldID = 0;
16 | picker = {};
17 | daterangeRequired = 0;
18 |
19 | /**
20 | * initialize()
21 | *
22 | * When initialize the form, listen to the radio chanel to see if there's a 'daterange' chanel.
23 | */
24 | initialize() {
25 | this.listenTo(radioChannel, "render:view", this.renderView);
26 |
27 | this.listenTo(
28 | submitChannel,
29 | "validate:field",
30 | this.validateRequiredField,
31 | );
32 | this.listenTo(submitChannel, "validate:field", this.saveField); // when a field isn't required
33 | this.listenTo(
34 | fieldsChannel,
35 | "change:model",
36 | this.useCustomRequiredField,
37 | );
38 | }
39 |
40 | /**
41 | * Use custom required field
42 | *
43 | * @param {*} model
44 | */
45 | useCustomRequiredField(model) {
46 | if (this.fieldType !== model.get("type")) {
47 | return true;
48 | }
49 | if (0 === model.get("required")) {
50 | return;
51 | }
52 | if ({} === this.picker) {
53 | return true;
54 | }
55 |
56 | if (
57 | typeof this.picker.getDate === "function" &&
58 | null == this.picker.getDate()
59 | ) {
60 | this.daterangeRequired = 1;
61 | this.fieldID = model.get("id");
62 | model.set("required", 0);
63 | }
64 | return true;
65 | }
66 |
67 | /**
68 | * validateRequireField()
69 | *
70 | * For required data rage field, check that it has a value.
71 | * Saves validated dates.
72 | *
73 | * @param {*} model
74 | */
75 | validateRequiredField(model) {
76 | if (this.fieldType !== model.get("type")) {
77 | return true;
78 | }
79 | if (0 === this.daterangeRequired) {
80 | return;
81 | }
82 | if (!this.picker) {
83 | return true;
84 | }
85 |
86 | if (
87 | true ===
88 | dayjs(this.picker.getDate(), this.getDateFormat(model), true).isValid()
89 | ) {
90 | this.addDates(model);
91 | // Remove Error from Model
92 | fieldsChannel.request(
93 | "remove:error",
94 | model.get("id"),
95 | "required-error",
96 | );
97 | } else {
98 | // Add Error to Model
99 | fieldsChannel.request(
100 | "add:error",
101 | model.get("id"),
102 | "required-error",
103 | nfi18n.validateRequiredField,
104 | );
105 | }
106 | }
107 |
108 | /**
109 | * saveField()
110 | *
111 | * Used when the field is not required.
112 | *
113 | * @param {*} model
114 | */
115 | saveField(model) {
116 | if (this.fieldType !== model.get("type")) {
117 | return true;
118 | }
119 | if (1 === this.daterangeRequired) {
120 | return true;
121 | }
122 | if (!this.picker) {
123 | return true;
124 | }
125 |
126 | if (
127 | typeof this.picker.getDate === "function" &&
128 | null != this.picker.getDate() &&
129 | this.picker.getDate() > 0
130 | ) {
131 | this.addDates(model);
132 | }
133 | }
134 |
135 | /**
136 | * addDates()
137 | *
138 | * Add dates to the model.
139 | *
140 | * @param {*} model
141 | */
142 | addDates(model) {
143 | const dateFormat = this.getDateFormat(model);
144 | const startDate = dayjs(this.picker.getStartDate()).format(dateFormat);
145 | const endDate = dayjs(this.picker.getEndDate()).format(dateFormat);
146 | model.set("value", `${startDate} - ${endDate}`);
147 | }
148 |
149 | /**
150 | * renderView()
151 | *
152 | * When rendering the form (i.e. the view), attach custom javascript code and events.
153 | */
154 | renderView(view) {
155 | const litepickerConfig = {
156 | element: view.el.getElementsByClassName("daterange")[0],
157 | firstDay: view.model.get("start_of_week"),
158 | format: this.getDateFormat(view.model),
159 | lang: () => {
160 | let lang = drDateRange.lang.replace("_", "-");
161 | try {
162 | Intl.getCanonicalLocales(lang);
163 | } catch (error) {
164 | console.error(
165 | "Invalid date format: %s. Should look something like this: en-US",
166 | lang,
167 | );
168 | let lang = "en-US";
169 | }
170 | return lang;
171 | },
172 | singleMode: 0,
173 | disableWeekends: view.model.get("disable_weekends"),
174 | numberOfMonths: 2,
175 | numberOfColumns: 2,
176 | showWeekNumbers: view.model.get("show_week_numbers"),
177 | selectBackward: view.model.get("select_backward"),
178 | selectForward: view.model.get("select_forward"),
179 | showTooltip: view.model.get("tooltip"),
180 | autoApply: view.model.get("auto_apply"),
181 | onShow: () => {
182 | fieldsChannel.request(
183 | "remove:error",
184 | this.fieldID,
185 | "required-error",
186 | );
187 | },
188 | };
189 |
190 | if (0 !== litepickerConfig.showTooltip) {
191 | litepickerConfig.tooltipText = {
192 | one: view.model.get("tooltip_singular"),
193 | other: view.model.get("tooltip_plural"),
194 | };
195 | }
196 |
197 | if (0 !== view.model.get("max_min_date")) {
198 | const minMaxDateStart = view.model.get("min_date");
199 | const minMaxDateEnd = view.model.get("max_date");
200 |
201 | if (typeof minMaxDateStart !== "undefined" && minMaxDateStart !== "") {
202 | if (this.isValidDate(minMaxDateStart)) {
203 | litepickerConfig.minDate = minMaxDateStart;
204 | } else {
205 | console.error(
206 | "Invalid date format: %s. Valid is YYYY-MM-YY. E.g.: 2020-02-29",
207 | minMaxDateStart,
208 | );
209 | }
210 | }
211 |
212 | if (typeof minMaxDateEnd !== "undefined" && minMaxDateEnd !== "") {
213 | if (this.isValidDate(minMaxDateEnd)) {
214 | litepickerConfig.maxDate = minMaxDateEnd;
215 | } else {
216 | console.error(
217 | "Invalid date format: %s. Valid is YYYY-MM-YY. E.g.: 2020-02-29",
218 | minMaxDateEnd,
219 | );
220 | }
221 | }
222 | }
223 |
224 | if (0 !== view.model.get("min_max_days")) {
225 | const minMaxDaysMin = view.model.get("min_days");
226 | const minMaxDaysMax = view.model.get("max_days");
227 |
228 | if (
229 | typeof minMaxDaysMin !== "undefined" &&
230 | minMaxDaysMin !== "" &&
231 | minMaxDaysMin > 0
232 | ) {
233 | litepickerConfig.minDays = minMaxDaysMin - 1;
234 | }
235 |
236 | if (
237 | typeof minMaxDaysMax !== "undefined" &&
238 | minMaxDaysMax !== "" &&
239 | minMaxDaysMax > 0
240 | ) {
241 | litepickerConfig.maxDays = minMaxDaysMax - 1;
242 | }
243 | }
244 |
245 | if (
246 | typeof drDateRange.dropdowns !== "undefined" &&
247 | drDateRange.dropdowns !== "[]"
248 | ) {
249 | litepickerConfig.dropdowns = drDateRange.dropdowns;
250 | }
251 |
252 | if (
253 | typeof drDateRange.buttontext !== "undefined" &&
254 | drDateRange.buttontext !== "[]"
255 | ) {
256 | litepickerConfig.buttonText = drDateRange.buttontext;
257 | }
258 |
259 | // https://wakirin.github.io/Litepicker/
260 | this.picker = new Litepicker(litepickerConfig);
261 | }
262 |
263 | /**
264 | *
265 | * @param {*} model
266 | */
267 | getDateFormat(model) {
268 | let dateFormat = model.get("date_format");
269 | if ("" === dateFormat || "default" === dateFormat) {
270 | dateFormat = this.convertDateFormat(drDateRange.dateFormat); // 'DateRange' from wp_localize in date-range-ninja-forms.php
271 | }
272 | return dateFormat;
273 | }
274 |
275 | /**
276 | * from https://github.com/wpninjas/ninja-forms/blob/83cccc6815c98a7ef50ca62704b2661eb53dd3cc/assets/js/front-end/controllers/fieldDate.js#L77-L136
277 | * @param {*} dateFormat
278 | */
279 | convertDateFormat(dateFormat) {
280 | // http://php.net/manual/en/function.date.php
281 | // https://github.com/dbushell/Pikaday/blob/master/README.md#formatting
282 | // Note: Be careful not to add overriding replacements. Order is important here.
283 | /** Day*/
284 | dateFormat = dateFormat.replace("D", "ddd"); // @todo Ordering issue?
285 | dateFormat = dateFormat.replace("d", "DD");
286 | dateFormat = dateFormat.replace("l", "dddd");
287 | dateFormat = dateFormat.replace("j", "D");
288 | dateFormat = dateFormat.replace("N", ""); // Not Supported
289 | dateFormat = dateFormat.replace("S", ""); // Not Supported
290 | dateFormat = dateFormat.replace("w", "d");
291 | dateFormat = dateFormat.replace("z", ""); // Not Supported
292 |
293 | /** Week*/
294 | dateFormat = dateFormat.replace("W", "W");
295 |
296 | /** Month*/
297 | dateFormat = dateFormat.replace("M", "MMM"); // "M" before "F" or "m" to avoid overriding.
298 | dateFormat = dateFormat.replace("F", "MMMM");
299 | dateFormat = dateFormat.replace("m", "MM");
300 | dateFormat = dateFormat.replace("n", "M");
301 | dateFormat = dateFormat.replace("t", ""); // Not Supported
302 |
303 | // Year
304 | dateFormat = dateFormat.replace("L", ""); // Not Supported
305 | dateFormat = dateFormat.replace("o", "YYYY");
306 | dateFormat = dateFormat.replace("Y", "YYYY");
307 | dateFormat = dateFormat.replace("y", "YY");
308 |
309 | // Time - Not supported
310 | dateFormat = dateFormat.replace("a", "");
311 | dateFormat = dateFormat.replace("A", "");
312 | dateFormat = dateFormat.replace("B", "");
313 | dateFormat = dateFormat.replace("g", "");
314 | dateFormat = dateFormat.replace("G", "");
315 | dateFormat = dateFormat.replace("h", "");
316 | dateFormat = dateFormat.replace("H", "");
317 | dateFormat = dateFormat.replace("i", "");
318 | dateFormat = dateFormat.replace("s", "");
319 | dateFormat = dateFormat.replace("u", "");
320 | dateFormat = dateFormat.replace("v", "");
321 |
322 | // Timezone - Not supported
323 | dateFormat = dateFormat.replace("e", "");
324 | dateFormat = dateFormat.replace("I", "");
325 | dateFormat = dateFormat.replace("O", "");
326 | dateFormat = dateFormat.replace("P", "");
327 | dateFormat = dateFormat.replace("T", "");
328 | dateFormat = dateFormat.replace("Z", "");
329 |
330 | // Full Date/Time - Not Supported
331 | dateFormat = dateFormat.replace("c", "");
332 | dateFormat = dateFormat.replace("r", "");
333 | dateFormat = dateFormat.replace("u", "");
334 |
335 | return dateFormat;
336 | }
337 |
338 | /**
339 | * From: https://stackoverflow.com/a/35413963
340 | * @param {*} dateString
341 | */
342 | isValidDate(dateString) {
343 | const regEx = /^\d{4}-\d{2}-\d{2}$/;
344 | if (!dateString.match(regEx)) {
345 | return false;
346 | } // Invalid format
347 | const d = new Date(dateString);
348 | const dNum = d.getTime();
349 | if (!dNum && dNum !== 0) {
350 | return false;
351 | } // NaN value, Invalid date
352 | return d.toISOString().slice(0, 10) === dateString;
353 | }
354 | };
355 |
356 | new DateRange();
357 | },
358 | );
359 |
--------------------------------------------------------------------------------
/vendor/composer/ClassLoader.php:
--------------------------------------------------------------------------------
1 |
7 | * Jordi Boggiano
8 | *
9 | * For the full copyright and license information, please view the LICENSE
10 | * file that was distributed with this source code.
11 | */
12 |
13 | namespace Composer\Autoload;
14 |
15 | /**
16 | * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
17 | *
18 | * $loader = new \Composer\Autoload\ClassLoader();
19 | *
20 | * // register classes with namespaces
21 | * $loader->add('Symfony\Component', __DIR__.'/component');
22 | * $loader->add('Symfony', __DIR__.'/framework');
23 | *
24 | * // activate the autoloader
25 | * $loader->register();
26 | *
27 | * // to enable searching the include path (eg. for PEAR packages)
28 | * $loader->setUseIncludePath(true);
29 | *
30 | * In this example, if you try to use a class in the Symfony\Component
31 | * namespace or one of its children (Symfony\Component\Console for instance),
32 | * the autoloader will first look for the class under the component/
33 | * directory, and it will then fallback to the framework/ directory if not
34 | * found before giving up.
35 | *
36 | * This class is loosely based on the Symfony UniversalClassLoader.
37 | *
38 | * @author Fabien Potencier
39 | * @author Jordi Boggiano
40 | * @see https://www.php-fig.org/psr/psr-0/
41 | * @see https://www.php-fig.org/psr/psr-4/
42 | */
43 | class ClassLoader
44 | {
45 | private $vendorDir;
46 |
47 | // PSR-4
48 | private $prefixLengthsPsr4 = array();
49 | private $prefixDirsPsr4 = array();
50 | private $fallbackDirsPsr4 = array();
51 |
52 | // PSR-0
53 | private $prefixesPsr0 = array();
54 | private $fallbackDirsPsr0 = array();
55 |
56 | private $useIncludePath = false;
57 | private $classMap = array();
58 | private $classMapAuthoritative = false;
59 | private $missingClasses = array();
60 | private $apcuPrefix;
61 |
62 | private static $registeredLoaders = array();
63 |
64 | public function __construct($vendorDir = null)
65 | {
66 | $this->vendorDir = $vendorDir;
67 | }
68 |
69 | public function getPrefixes()
70 | {
71 | if (!empty($this->prefixesPsr0)) {
72 | return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
73 | }
74 |
75 | return array();
76 | }
77 |
78 | public function getPrefixesPsr4()
79 | {
80 | return $this->prefixDirsPsr4;
81 | }
82 |
83 | public function getFallbackDirs()
84 | {
85 | return $this->fallbackDirsPsr0;
86 | }
87 |
88 | public function getFallbackDirsPsr4()
89 | {
90 | return $this->fallbackDirsPsr4;
91 | }
92 |
93 | public function getClassMap()
94 | {
95 | return $this->classMap;
96 | }
97 |
98 | /**
99 | * @param array $classMap Class to filename map
100 | */
101 | public function addClassMap(array $classMap)
102 | {
103 | if ($this->classMap) {
104 | $this->classMap = array_merge($this->classMap, $classMap);
105 | } else {
106 | $this->classMap = $classMap;
107 | }
108 | }
109 |
110 | /**
111 | * Registers a set of PSR-0 directories for a given prefix, either
112 | * appending or prepending to the ones previously set for this prefix.
113 | *
114 | * @param string $prefix The prefix
115 | * @param array|string $paths The PSR-0 root directories
116 | * @param bool $prepend Whether to prepend the directories
117 | */
118 | public function add($prefix, $paths, $prepend = false)
119 | {
120 | if (!$prefix) {
121 | if ($prepend) {
122 | $this->fallbackDirsPsr0 = array_merge(
123 | (array) $paths,
124 | $this->fallbackDirsPsr0
125 | );
126 | } else {
127 | $this->fallbackDirsPsr0 = array_merge(
128 | $this->fallbackDirsPsr0,
129 | (array) $paths
130 | );
131 | }
132 |
133 | return;
134 | }
135 |
136 | $first = $prefix[0];
137 | if (!isset($this->prefixesPsr0[$first][$prefix])) {
138 | $this->prefixesPsr0[$first][$prefix] = (array) $paths;
139 |
140 | return;
141 | }
142 | if ($prepend) {
143 | $this->prefixesPsr0[$first][$prefix] = array_merge(
144 | (array) $paths,
145 | $this->prefixesPsr0[$first][$prefix]
146 | );
147 | } else {
148 | $this->prefixesPsr0[$first][$prefix] = array_merge(
149 | $this->prefixesPsr0[$first][$prefix],
150 | (array) $paths
151 | );
152 | }
153 | }
154 |
155 | /**
156 | * Registers a set of PSR-4 directories for a given namespace, either
157 | * appending or prepending to the ones previously set for this namespace.
158 | *
159 | * @param string $prefix The prefix/namespace, with trailing '\\'
160 | * @param array|string $paths The PSR-4 base directories
161 | * @param bool $prepend Whether to prepend the directories
162 | *
163 | * @throws \InvalidArgumentException
164 | */
165 | public function addPsr4($prefix, $paths, $prepend = false)
166 | {
167 | if (!$prefix) {
168 | // Register directories for the root namespace.
169 | if ($prepend) {
170 | $this->fallbackDirsPsr4 = array_merge(
171 | (array) $paths,
172 | $this->fallbackDirsPsr4
173 | );
174 | } else {
175 | $this->fallbackDirsPsr4 = array_merge(
176 | $this->fallbackDirsPsr4,
177 | (array) $paths
178 | );
179 | }
180 | } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
181 | // Register directories for a new namespace.
182 | $length = strlen($prefix);
183 | if ('\\' !== $prefix[$length - 1]) {
184 | throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
185 | }
186 | $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
187 | $this->prefixDirsPsr4[$prefix] = (array) $paths;
188 | } elseif ($prepend) {
189 | // Prepend directories for an already registered namespace.
190 | $this->prefixDirsPsr4[$prefix] = array_merge(
191 | (array) $paths,
192 | $this->prefixDirsPsr4[$prefix]
193 | );
194 | } else {
195 | // Append directories for an already registered namespace.
196 | $this->prefixDirsPsr4[$prefix] = array_merge(
197 | $this->prefixDirsPsr4[$prefix],
198 | (array) $paths
199 | );
200 | }
201 | }
202 |
203 | /**
204 | * Registers a set of PSR-0 directories for a given prefix,
205 | * replacing any others previously set for this prefix.
206 | *
207 | * @param string $prefix The prefix
208 | * @param array|string $paths The PSR-0 base directories
209 | */
210 | public function set($prefix, $paths)
211 | {
212 | if (!$prefix) {
213 | $this->fallbackDirsPsr0 = (array) $paths;
214 | } else {
215 | $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
216 | }
217 | }
218 |
219 | /**
220 | * Registers a set of PSR-4 directories for a given namespace,
221 | * replacing any others previously set for this namespace.
222 | *
223 | * @param string $prefix The prefix/namespace, with trailing '\\'
224 | * @param array|string $paths The PSR-4 base directories
225 | *
226 | * @throws \InvalidArgumentException
227 | */
228 | public function setPsr4($prefix, $paths)
229 | {
230 | if (!$prefix) {
231 | $this->fallbackDirsPsr4 = (array) $paths;
232 | } else {
233 | $length = strlen($prefix);
234 | if ('\\' !== $prefix[$length - 1]) {
235 | throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
236 | }
237 | $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
238 | $this->prefixDirsPsr4[$prefix] = (array) $paths;
239 | }
240 | }
241 |
242 | /**
243 | * Turns on searching the include path for class files.
244 | *
245 | * @param bool $useIncludePath
246 | */
247 | public function setUseIncludePath($useIncludePath)
248 | {
249 | $this->useIncludePath = $useIncludePath;
250 | }
251 |
252 | /**
253 | * Can be used to check if the autoloader uses the include path to check
254 | * for classes.
255 | *
256 | * @return bool
257 | */
258 | public function getUseIncludePath()
259 | {
260 | return $this->useIncludePath;
261 | }
262 |
263 | /**
264 | * Turns off searching the prefix and fallback directories for classes
265 | * that have not been registered with the class map.
266 | *
267 | * @param bool $classMapAuthoritative
268 | */
269 | public function setClassMapAuthoritative($classMapAuthoritative)
270 | {
271 | $this->classMapAuthoritative = $classMapAuthoritative;
272 | }
273 |
274 | /**
275 | * Should class lookup fail if not found in the current class map?
276 | *
277 | * @return bool
278 | */
279 | public function isClassMapAuthoritative()
280 | {
281 | return $this->classMapAuthoritative;
282 | }
283 |
284 | /**
285 | * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
286 | *
287 | * @param string|null $apcuPrefix
288 | */
289 | public function setApcuPrefix($apcuPrefix)
290 | {
291 | $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
292 | }
293 |
294 | /**
295 | * The APCu prefix in use, or null if APCu caching is not enabled.
296 | *
297 | * @return string|null
298 | */
299 | public function getApcuPrefix()
300 | {
301 | return $this->apcuPrefix;
302 | }
303 |
304 | /**
305 | * Registers this instance as an autoloader.
306 | *
307 | * @param bool $prepend Whether to prepend the autoloader or not
308 | */
309 | public function register($prepend = false)
310 | {
311 | spl_autoload_register(array($this, 'loadClass'), true, $prepend);
312 |
313 | if (null === $this->vendorDir) {
314 | return;
315 | }
316 |
317 | if ($prepend) {
318 | self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
319 | } else {
320 | unset(self::$registeredLoaders[$this->vendorDir]);
321 | self::$registeredLoaders[$this->vendorDir] = $this;
322 | }
323 | }
324 |
325 | /**
326 | * Unregisters this instance as an autoloader.
327 | */
328 | public function unregister()
329 | {
330 | spl_autoload_unregister(array($this, 'loadClass'));
331 |
332 | if (null !== $this->vendorDir) {
333 | unset(self::$registeredLoaders[$this->vendorDir]);
334 | }
335 | }
336 |
337 | /**
338 | * Loads the given class or interface.
339 | *
340 | * @param string $class The name of the class
341 | * @return bool|null True if loaded, null otherwise
342 | */
343 | public function loadClass($class)
344 | {
345 | if ($file = $this->findFile($class)) {
346 | includeFile($file);
347 |
348 | return true;
349 | }
350 | }
351 |
352 | /**
353 | * Finds the path to the file where the class is defined.
354 | *
355 | * @param string $class The name of the class
356 | *
357 | * @return string|false The path if found, false otherwise
358 | */
359 | public function findFile($class)
360 | {
361 | // class map lookup
362 | if (isset($this->classMap[$class])) {
363 | return $this->classMap[$class];
364 | }
365 | if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
366 | return false;
367 | }
368 | if (null !== $this->apcuPrefix) {
369 | $file = apcu_fetch($this->apcuPrefix.$class, $hit);
370 | if ($hit) {
371 | return $file;
372 | }
373 | }
374 |
375 | $file = $this->findFileWithExtension($class, '.php');
376 |
377 | // Search for Hack files if we are running on HHVM
378 | if (false === $file && defined('HHVM_VERSION')) {
379 | $file = $this->findFileWithExtension($class, '.hh');
380 | }
381 |
382 | if (null !== $this->apcuPrefix) {
383 | apcu_add($this->apcuPrefix.$class, $file);
384 | }
385 |
386 | if (false === $file) {
387 | // Remember that this class does not exist.
388 | $this->missingClasses[$class] = true;
389 | }
390 |
391 | return $file;
392 | }
393 |
394 | /**
395 | * Returns the currently registered loaders indexed by their corresponding vendor directories.
396 | *
397 | * @return self[]
398 | */
399 | public static function getRegisteredLoaders()
400 | {
401 | return self::$registeredLoaders;
402 | }
403 |
404 | private function findFileWithExtension($class, $ext)
405 | {
406 | // PSR-4 lookup
407 | $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
408 |
409 | $first = $class[0];
410 | if (isset($this->prefixLengthsPsr4[$first])) {
411 | $subPath = $class;
412 | while (false !== $lastPos = strrpos($subPath, '\\')) {
413 | $subPath = substr($subPath, 0, $lastPos);
414 | $search = $subPath . '\\';
415 | if (isset($this->prefixDirsPsr4[$search])) {
416 | $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
417 | foreach ($this->prefixDirsPsr4[$search] as $dir) {
418 | if (file_exists($file = $dir . $pathEnd)) {
419 | return $file;
420 | }
421 | }
422 | }
423 | }
424 | }
425 |
426 | // PSR-4 fallback dirs
427 | foreach ($this->fallbackDirsPsr4 as $dir) {
428 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
429 | return $file;
430 | }
431 | }
432 |
433 | // PSR-0 lookup
434 | if (false !== $pos = strrpos($class, '\\')) {
435 | // namespaced class name
436 | $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
437 | . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
438 | } else {
439 | // PEAR-like class name
440 | $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
441 | }
442 |
443 | if (isset($this->prefixesPsr0[$first])) {
444 | foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
445 | if (0 === strpos($class, $prefix)) {
446 | foreach ($dirs as $dir) {
447 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
448 | return $file;
449 | }
450 | }
451 | }
452 | }
453 | }
454 |
455 | // PSR-0 fallback dirs
456 | foreach ($this->fallbackDirsPsr0 as $dir) {
457 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
458 | return $file;
459 | }
460 | }
461 |
462 | // PSR-0 include paths.
463 | if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
464 | return $file;
465 | }
466 |
467 | return false;
468 | }
469 | }
470 |
471 | /**
472 | * Scope isolated include.
473 | *
474 | * Prevents access to $this/self from included files.
475 | */
476 | function includeFile($file)
477 | {
478 | include $file;
479 | }
480 |
--------------------------------------------------------------------------------