From 2619410bb4f581ae874bc610dcf9d3c7e048c59a Mon Sep 17 00:00:00 2001 From: merdan Date: Mon, 15 Mar 2021 11:23:49 +0500 Subject: [PATCH] view statistics --- .../Composer/Installers/WinterInstaller.php | 47 + .../Installers/Test/WinterInstallerTest.php | 89 + plugins/pollozen/mostvisited/Plugin.php | 52 + plugins/pollozen/mostvisited/README.md | 58 + .../mostvisited/components/RegisterVisit.php | 32 + .../mostvisited/components/TopVisited.php | 196 + .../components/registervisit/default.htm | 1 + .../components/topvisited/default.htm | 18 + .../pollozen/mostvisited/models/Visits.php | 37 + .../mostvisited/models/visits/columns.yaml | 8 + .../mostvisited/models/visits/fields.yaml | 8 + .../updates/create_visits_table.php | 27 + .../pollozen/mostvisited/updates/version.yaml | 5 + plugins/vdomah/blogviews/LICENCE.md | 19 + plugins/vdomah/blogviews/Plugin.php | 228 + plugins/vdomah/blogviews/README.md | 15 + .../vdomah/blogviews/components/Popular.php | 141 + plugins/vdomah/blogviews/components/Views.php | 63 + .../blogviews/components/popular/default.htm | 12 + .../blogviews/components/views/default.htm | 3 + plugins/vdomah/blogviews/lang/en/lang.php | 35 + plugins/vdomah/blogviews/models/Settings.php | 12 + .../blogviews/models/settings/fields.yaml | 10 + .../updates/create_post_views_table.php | 23 + plugins/vdomah/blogviews/updates/version.yaml | 31 + plugins/vdomah/blogviews/vendor/autoload.php | 7 + .../blogviews/vendor/composer/ClassLoader.php | 445 + .../vdomah/blogviews/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 9 + .../vendor/composer/autoload_files.php | 10 + .../vendor/composer/autoload_namespaces.php | 9 + .../vendor/composer/autoload_psr4.php | 10 + .../vendor/composer/autoload_real.php | 70 + .../vendor/composer/autoload_static.php | 35 + .../blogviews/vendor/composer/installed.json | 111 + .../vendor/mustangostang/spyc/COPYING | 21 + .../vendor/mustangostang/spyc/README.md | 30 + .../vendor/mustangostang/spyc/Spyc.php | 1186 ++ .../vendor/mustangostang/spyc/composer.json | 30 + .../mustangostang/spyc/examples/yaml-dump.php | 25 + .../mustangostang/spyc/examples/yaml-load.php | 21 + .../vendor/mustangostang/spyc/php4/5to4.php | 17 + .../vendor/mustangostang/spyc/php4/spyc.php4 | 1023 ++ .../vendor/mustangostang/spyc/php4/test.php4 | 162 + .../vendor/mustangostang/spyc/phpunit.xml | 8 + .../vendor/mustangostang/spyc/spyc.yaml | 219 + .../mustangostang/spyc/tests/DumpTest.php | 194 + .../mustangostang/spyc/tests/IndentTest.php | 68 + .../mustangostang/spyc/tests/LoadTest.php | 17 + .../mustangostang/spyc/tests/ParseTest.php | 413 + .../spyc/tests/RoundTripTest.php | 76 + .../mustangostang/spyc/tests/comments.yaml | 3 + .../mustangostang/spyc/tests/failing1.yaml | 2 + .../mustangostang/spyc/tests/indent_1.yaml | 70 + .../mustangostang/spyc/tests/quotes.yaml | 8 + .../piwik/device-detector/Cache/Cache.php | 22 + .../device-detector/Cache/PSR16Bridge.php | 63 + .../device-detector/Cache/PSR6Bridge.php | 68 + .../device-detector/Cache/StaticCache.php | 53 + .../piwik/device-detector/DeviceDetector.php | 895 + .../vendor/piwik/device-detector/LICENSE | 165 + .../piwik/device-detector/Parser/Bot.php | 70 + .../Parser/BotParserAbstract.php | 23 + .../device-detector/Parser/Client/Browser.php | 413 + .../Parser/Client/Browser/Engine.php | 79 + .../Parser/Client/Browser/Engine/Version.php | 54 + .../Parser/Client/ClientParserAbstract.php | 74 + .../Parser/Client/FeedReader.php | 21 + .../device-detector/Parser/Client/Library.php | 21 + .../Parser/Client/MediaPlayer.php | 21 + .../Parser/Client/MobileApp.php | 21 + .../device-detector/Parser/Client/PIM.php | 21 + .../device-detector/Parser/Device/Camera.php | 30 + .../Parser/Device/CarBrowser.php | 30 + .../device-detector/Parser/Device/Console.php | 30 + .../Parser/Device/DeviceParserAbstract.php | 832 + .../device-detector/Parser/Device/HbbTv.php | 53 + .../device-detector/Parser/Device/Mobile.php | 21 + .../Parser/Device/PortableMediaPlayer.php | 30 + .../Parser/OperatingSystem.php | 250 + .../device-detector/Parser/ParserAbstract.php | 329 + .../device-detector/Parser/VendorFragment.php | 44 + .../vendor/piwik/device-detector/README.md | 241 + .../piwik/device-detector/Yaml/Parser.php | 14 + .../piwik/device-detector/Yaml/Pecl.php | 37 + .../piwik/device-detector/Yaml/Spyc.php | 19 + .../piwik/device-detector/Yaml/Symfony.php | 20 + .../vendor/piwik/device-detector/autoload.php | 32 + .../piwik/device-detector/composer.json | 42 + .../piwik/device-detector/regexes/bots.yml | 2030 +++ .../regexes/client/browser_engine.yml | 36 + .../regexes/client/browsers.yml | 1584 ++ .../regexes/client/feed_readers.yml | 144 + .../regexes/client/libraries.yml | 108 + .../regexes/client/mediaplayers.yml | 102 + .../regexes/client/mobile_apps.yml | 216 + .../device-detector/regexes/client/pim.yml | 51 + .../regexes/device/cameras.yml | 28 + .../regexes/device/car_browsers.yml | 16 + .../regexes/device/consoles.yml | 40 + .../regexes/device/mobiles.yml | 13721 ++++++++++++++++ .../regexes/device/portable_media_player.yml | 59 + .../regexes/device/televisions.yml | 296 + .../piwik/device-detector/regexes/oss.yml | 776 + .../regexes/vendorfragments.yml | 75 + themes/modern/layouts/cms.htm | 8 +- themes/modern/layouts/contacts.htm | 10 +- themes/modern/layouts/master.htm | 4 +- themes/modern/layouts/static.htm | 11 +- themes/modern/pages/category.htm | 40 +- themes/modern/pages/index.htm | 1426 +- themes/modern/partials/pagination.htm | 37 + 112 files changed, 30395 insertions(+), 51 deletions(-) create mode 100644 plugins/janvince/smallcontactform/vendor/composer/installers/src/Composer/Installers/WinterInstaller.php create mode 100644 plugins/janvince/smallcontactform/vendor/composer/installers/tests/Composer/Installers/Test/WinterInstallerTest.php create mode 100644 plugins/pollozen/mostvisited/Plugin.php create mode 100644 plugins/pollozen/mostvisited/README.md create mode 100644 plugins/pollozen/mostvisited/components/RegisterVisit.php create mode 100644 plugins/pollozen/mostvisited/components/TopVisited.php create mode 100644 plugins/pollozen/mostvisited/components/registervisit/default.htm create mode 100644 plugins/pollozen/mostvisited/components/topvisited/default.htm create mode 100644 plugins/pollozen/mostvisited/models/Visits.php create mode 100644 plugins/pollozen/mostvisited/models/visits/columns.yaml create mode 100644 plugins/pollozen/mostvisited/models/visits/fields.yaml create mode 100644 plugins/pollozen/mostvisited/updates/create_visits_table.php create mode 100644 plugins/pollozen/mostvisited/updates/version.yaml create mode 100644 plugins/vdomah/blogviews/LICENCE.md create mode 100644 plugins/vdomah/blogviews/Plugin.php create mode 100644 plugins/vdomah/blogviews/README.md create mode 100644 plugins/vdomah/blogviews/components/Popular.php create mode 100644 plugins/vdomah/blogviews/components/Views.php create mode 100644 plugins/vdomah/blogviews/components/popular/default.htm create mode 100644 plugins/vdomah/blogviews/components/views/default.htm create mode 100644 plugins/vdomah/blogviews/lang/en/lang.php create mode 100644 plugins/vdomah/blogviews/models/Settings.php create mode 100644 plugins/vdomah/blogviews/models/settings/fields.yaml create mode 100644 plugins/vdomah/blogviews/updates/create_post_views_table.php create mode 100644 plugins/vdomah/blogviews/updates/version.yaml create mode 100644 plugins/vdomah/blogviews/vendor/autoload.php create mode 100644 plugins/vdomah/blogviews/vendor/composer/ClassLoader.php create mode 100644 plugins/vdomah/blogviews/vendor/composer/LICENSE create mode 100644 plugins/vdomah/blogviews/vendor/composer/autoload_classmap.php create mode 100644 plugins/vdomah/blogviews/vendor/composer/autoload_files.php create mode 100644 plugins/vdomah/blogviews/vendor/composer/autoload_namespaces.php create mode 100644 plugins/vdomah/blogviews/vendor/composer/autoload_psr4.php create mode 100644 plugins/vdomah/blogviews/vendor/composer/autoload_real.php create mode 100644 plugins/vdomah/blogviews/vendor/composer/autoload_static.php create mode 100644 plugins/vdomah/blogviews/vendor/composer/installed.json create mode 100644 plugins/vdomah/blogviews/vendor/mustangostang/spyc/COPYING create mode 100644 plugins/vdomah/blogviews/vendor/mustangostang/spyc/README.md create mode 100644 plugins/vdomah/blogviews/vendor/mustangostang/spyc/Spyc.php create mode 100644 plugins/vdomah/blogviews/vendor/mustangostang/spyc/composer.json create mode 100644 plugins/vdomah/blogviews/vendor/mustangostang/spyc/examples/yaml-dump.php create mode 100644 plugins/vdomah/blogviews/vendor/mustangostang/spyc/examples/yaml-load.php create mode 100644 plugins/vdomah/blogviews/vendor/mustangostang/spyc/php4/5to4.php create mode 100644 plugins/vdomah/blogviews/vendor/mustangostang/spyc/php4/spyc.php4 create mode 100644 plugins/vdomah/blogviews/vendor/mustangostang/spyc/php4/test.php4 create mode 100644 plugins/vdomah/blogviews/vendor/mustangostang/spyc/phpunit.xml create mode 100644 plugins/vdomah/blogviews/vendor/mustangostang/spyc/spyc.yaml create mode 100644 plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/DumpTest.php create mode 100644 plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/IndentTest.php create mode 100644 plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/LoadTest.php create mode 100644 plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/ParseTest.php create mode 100644 plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/RoundTripTest.php create mode 100644 plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/comments.yaml create mode 100644 plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/failing1.yaml create mode 100644 plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/indent_1.yaml create mode 100644 plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/quotes.yaml create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Cache/Cache.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Cache/PSR16Bridge.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Cache/PSR6Bridge.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Cache/StaticCache.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/DeviceDetector.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/LICENSE create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Bot.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/BotParserAbstract.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Client/Browser.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Client/Browser/Engine.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Client/Browser/Engine/Version.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Client/ClientParserAbstract.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Client/FeedReader.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Client/Library.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Client/MediaPlayer.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Client/MobileApp.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Client/PIM.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Device/Camera.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Device/CarBrowser.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Device/Console.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Device/DeviceParserAbstract.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Device/HbbTv.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Device/Mobile.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Device/PortableMediaPlayer.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/OperatingSystem.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/ParserAbstract.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/VendorFragment.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/README.md create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Yaml/Parser.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Yaml/Pecl.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Yaml/Spyc.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/Yaml/Symfony.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/autoload.php create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/composer.json create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/regexes/bots.yml create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/regexes/client/browser_engine.yml create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/regexes/client/browsers.yml create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/regexes/client/feed_readers.yml create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/regexes/client/libraries.yml create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/regexes/client/mediaplayers.yml create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/regexes/client/mobile_apps.yml create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/regexes/client/pim.yml create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/regexes/device/cameras.yml create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/regexes/device/car_browsers.yml create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/regexes/device/consoles.yml create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/regexes/device/mobiles.yml create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/regexes/device/portable_media_player.yml create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/regexes/device/televisions.yml create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/regexes/oss.yml create mode 100644 plugins/vdomah/blogviews/vendor/piwik/device-detector/regexes/vendorfragments.yml create mode 100644 themes/modern/partials/pagination.htm diff --git a/plugins/janvince/smallcontactform/vendor/composer/installers/src/Composer/Installers/WinterInstaller.php b/plugins/janvince/smallcontactform/vendor/composer/installers/src/Composer/Installers/WinterInstaller.php new file mode 100644 index 000000000..3dd841cb0 --- /dev/null +++ b/plugins/janvince/smallcontactform/vendor/composer/installers/src/Composer/Installers/WinterInstaller.php @@ -0,0 +1,47 @@ + 'modules/{$name}/', + 'plugin' => 'plugins/{$vendor}/{$name}/', + 'theme' => 'themes/{$name}/' + ); + + /** + * Format package name. + * + * For package type winter-plugin, cut off a trailing '-plugin' if present. + * + * For package type winter-theme, cut off a trailing '-theme' if present. + * + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] === 'winter-plugin') { + return $this->inflectPluginVars($vars); + } + + if ($vars['type'] === 'winter-theme') { + return $this->inflectThemeVars($vars); + } + + return $vars; + } + + protected function inflectPluginVars($vars) + { + $vars['name'] = preg_replace('/^oc-|-plugin$/', '', $vars['name']); + $vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']); + + return $vars; + } + + protected function inflectThemeVars($vars) + { + $vars['name'] = preg_replace('/^oc-|-theme$/', '', $vars['name']); + + return $vars; + } +} diff --git a/plugins/janvince/smallcontactform/vendor/composer/installers/tests/Composer/Installers/Test/WinterInstallerTest.php b/plugins/janvince/smallcontactform/vendor/composer/installers/tests/Composer/Installers/Test/WinterInstallerTest.php new file mode 100644 index 000000000..7bcb5a45f --- /dev/null +++ b/plugins/janvince/smallcontactform/vendor/composer/installers/tests/Composer/Installers/Test/WinterInstallerTest.php @@ -0,0 +1,89 @@ +installer = new WinterInstaller( + new Package('NyanCat', '4.2', '4.2'), + new Composer() + ); + } + + /** + * @dataProvider packageNameInflectionProvider + */ + public function testInflectPackageVars($type, $vendor, $name, $expectedVendor, $expectedName) + { + $this->assertEquals( + $this->installer->inflectPackageVars(array( + 'vendor' => $vendor, + 'name' => $name, + 'type' => $type + )), + array('vendor' => $expectedVendor, 'name' => $expectedName, 'type' => $type) + ); + } + + public function packageNameInflectionProvider() + { + return array( + array( + 'winter-plugin', + 'acme', + 'subpagelist', + 'acme', + 'subpagelist', + ), + array( + 'winter-plugin', + 'acme', + 'subpagelist-plugin', + 'acme', + 'subpagelist', + ), + array( + 'winter-plugin', + 'acme', + 'semanticwinter', + 'acme', + 'semanticwinter', + ), + // tests vendor name containing a hyphen + array( + 'winter-plugin', + 'foo-bar-co', + 'blog', + 'foobarco', + 'blog' + ), + // tests that exactly one '-theme' is cut off + array( + 'winter-theme', + 'acme', + 'some-theme-theme', + 'acme', + 'some-theme', + ), + // tests that names without '-theme' suffix stay valid + array( + 'winter-theme', + 'acme', + 'someothertheme', + 'acme', + 'someothertheme', + ), + ); + } +} diff --git a/plugins/pollozen/mostvisited/Plugin.php b/plugins/pollozen/mostvisited/Plugin.php new file mode 100644 index 000000000..8b57c662b --- /dev/null +++ b/plugins/pollozen/mostvisited/Plugin.php @@ -0,0 +1,52 @@ + 'Most Visited Posts', + 'description' => 'Register visit to RainLab Blog publication and retrieve the most visited publications', + 'author' => 'PolloZen', + 'icon' => 'icon-list-ul' + ]; + } + + /** + * Boot method, called right before the request route. + * + * @return array + */ + public function boot(){ + PostModel::extend(function($model){ + $model->hasMany['visits'] = ['PolloZen\MostVisited\Models\Visits']; + }); + + } + + /** + * Registers any front-end components implemented in this plugin. + * + * @return array + */ + public function registerComponents(){ + + return [ + 'PolloZen\MostVisited\Components\RegisterVisit' => 'registerVisit', + 'PolloZen\MostVisited\Components\TopVisited' => 'topPosts', + ]; + } +} diff --git a/plugins/pollozen/mostvisited/README.md b/plugins/pollozen/mostvisited/README.md new file mode 100644 index 000000000..effca54b5 --- /dev/null +++ b/plugins/pollozen/mostvisited/README.md @@ -0,0 +1,58 @@ +#Most Visited Post for [RainLab Blog](https://octobercms.com/plugin/rainlab-blog) + +Plugin to register visits to [RainLab Blog](https://octobercms.com/plugin/rainlab-blog) Blog Publications and create a list of the most visited posts in a period of time + +##Installing the watcher +**IMPORTANT** + +In order to register the visit to a Publication `RegisterVisit` component must be added to Post Page + +##Create a most visited posts list +Add the `TopVisitedComponent` + +This component has parameters + +**Most Visited From** - The time period to get the most visited publications + +- Today +- Current Week +- Last Week +- All the time + +**Category filter** + +You can select a category filter, this way you can get the Top 10 from a particular category. If no category is selected, the component will retrieve the top 10 from all your publications + +**Top** + +How many publications must be retrieved + +###Examples + +Using these three parameters you can construct different lists. Eg. + +- **Last week**, top **10** from **local news** +- **Today** top **5** from **all the site** +- Top **10** from **all the site** in **all the time** + +###Displaying the results +The `TopVisitedComponent` inject the **mostVisitedPosts** object + + + +Use as you already use the RainLab blog post + +``` +{% for post in mostVisitedPosts %} +
+
+
+

{{post.title}}

+ Continue reading +
+
+{% endfor %} +``` + +##Support and bugs reporting +You can write in the forum or visit me in [Github](https://github.com/sanPuerquitoProgramador/most-visited-posts) \ No newline at end of file diff --git a/plugins/pollozen/mostvisited/components/RegisterVisit.php b/plugins/pollozen/mostvisited/components/RegisterVisit.php new file mode 100644 index 000000000..b57105b4c --- /dev/null +++ b/plugins/pollozen/mostvisited/components/RegisterVisit.php @@ -0,0 +1,32 @@ + 'Register Visit', + 'description' => 'Attach this component to your blog post page/partial in order to register the user visit' + ]; + } + + public function defineProperties() + { + return []; + } + public function onRun(){ + if($this->page[ 'post' ]){ + if($this->page[ 'post' ]->id){ + $idPost = $this->page[ 'post' ]->id; + $today = Carbon::today(); + $visit = new Visits; + $visit = $visit->firstOrCreate(['post_id'=>$idPost, 'date'=>$today]); + $visit->whereId($visit->id)->increment('visits'); + } + } + } +} diff --git a/plugins/pollozen/mostvisited/components/TopVisited.php b/plugins/pollozen/mostvisited/components/TopVisited.php new file mode 100644 index 000000000..7a835987b --- /dev/null +++ b/plugins/pollozen/mostvisited/components/TopVisited.php @@ -0,0 +1,196 @@ + 'Top Visited Component', + 'description' => 'Retrieve the top visited RainLab Blog Posts' + ]; + } + /** + * Definition of propertys + * @return [array] + */ + public function defineProperties() + { + return [ + 'period' =>[ + 'title' => 'Most visited from:', + 'description' => '', + 'default' => 2, + 'type' => 'dropdown', + 'options' => [ + '1' => 'Today', + '2' => 'Current week', + '3' => 'Yesterday', + '4' => 'Last week', + '5' => 'All time' + ], + 'showExternalParam' => false + ], + 'category' =>[ + 'title' => 'Category Filter', + 'description' => 'Filter result by category. All categories by default', + 'type' => 'dropdown', + 'placeholder' => 'Select a category', + 'showExternalParam' => false, + 'default' => 0 + ], + 'postPerPage' => [ + 'title' => 'Top', + 'description' => 'How many results must be fetched', + 'default' => 5, + 'type' => 'string' + ], + 'postPage' => [ + 'title' => 'Post page', + 'description' => 'Page to show linked posts', + 'type' => 'dropdown', + 'default' => 'blog/post', + 'group' => 'Links', + ], + 'slug' => [ + 'title' => 'rainlab.blog::lang.settings.post_slug', + 'description' => 'rainlab.blog::lang.settings.post_slug_description', + 'default' => '{{ :slug }}', + 'type' => 'string', + 'group' => 'Links' + ] + ]; + } + /** + * [getPostPageOptions] + * @return [array][Blog] + */ + public function getPostPageOptions() + { + return Page::sortBy('baseFileName')->lists('baseFileName', 'baseFileName'); + } + /** + * [getCategoryOptions] + * @return [array list] [Blog Categories] + */ + public function getCategoryOptions(){ + $categories = [0=>'No filter'] + Category::orderBy('name')->lists('name','id'); + return $categories; + } + public function onRun(){ + $this->prepareVars(); + $this->mostVisitedPosts = $this->page['mostVisitedPosts'] = $this->getMostVisitedPosts(); + + } + + /** + * prepare Vars function + * @return [object] + */ + protected function prepareVars() { + /*Get the category filter*/ + $this->category = ($this->property('category')!=0) ? $this->property('category') : null; + + /* Get post page */ + $this->postPage = $this->property('postPage') ? $this->property('postPage') : '404'; + + /* Top */ + $this->postPerPage = is_int($this->property('postPerPage')) ? $this->property('postPerPage') : 5; + } + + + /** + * getTop Function [Obtiene los Post ID del rango y categorua seleccionados] + * @return [type] [description] + */ + protected function getTop(){ + switch($this->property('period')){ + case '1': + $dateRange = Carbon::today(); + break; + case '2': + $fromDate = Carbon::now()->startOfWeek()->format('Y-m-d'); + $toDate = Carbon::now()->endOfWeek()->format('Y-m-d'); + break; + case '3': + $dateRange = Carbon::yesterday(); + break; + case '4': + $fromDate = Carbon::now()->subDays(7)->startOfWeek()->format('Y/m/d'); + $toDate = Carbon::now()->subDays(7)->endOfWeek()->format('Y/m/d'); + break; + default: + // Si no hay fecha se toman todos + break; + } + + $v = Visits::select('pollozen_mostvisited_visits.post_id'); + + if(isset($dateRange)){ + $v->where('date',$dateRange); + } elseif (isset($fromDate)) { + $v->whereBetween('date', array($fromDate, $toDate)); + } + + $v ->selectRaw('sum(visits) as visits, count(pollozen_mostvisited_visits.post_id) as touchs') + ->groupBy('post_id') + ->orderBy('visits','desc'); + + if($this->category !== null){ + $v->join('rainlab_blog_posts_categories',function($join){ + $join ->on('pollozen_mostvisited_visits.post_id','=','rainlab_blog_posts_categories.post_id') + ->where('rainlab_blog_posts_categories.category_id','=',$this->category); + }); + } + + $v->limit($this->property('postPerPage')); + $topIds = $v -> lists('post_id'); + + return $topIds; + } + + protected function getMostVisitedPosts(){ + /* Obtenemos los ID de los más visitados en el rango solicitado */ + $topIds = $this->getTop(); + if(count($topIds)!=0){ + $placeholders = implode(',', array_fill(0, count($topIds), '?')) ; + + /* Empezamos con el objeto de los posts en general que estén publicados*/ + $p = Post::isPublished(); + $p->whereIn('id', $topIds); + $p->orderByRaw("FIELD(id,{$placeholders})",$topIds); + $mostVisitedPosts = $p->get(); + + /* Agregamos el helper de la URL*/ + $mostVisitedPosts->each(function($post) { + $post->setUrl($this->postPage,$this->controller); + }); + /* Mandamos los resultados */ + return $mostVisitedPosts; + } else { + return []; + } + } +} diff --git a/plugins/pollozen/mostvisited/components/registervisit/default.htm b/plugins/pollozen/mostvisited/components/registervisit/default.htm new file mode 100644 index 000000000..7b3cab4af --- /dev/null +++ b/plugins/pollozen/mostvisited/components/registervisit/default.htm @@ -0,0 +1 @@ +

Nothing to see here. This component is added to the post page in order to register the visit

\ No newline at end of file diff --git a/plugins/pollozen/mostvisited/components/topvisited/default.htm b/plugins/pollozen/mostvisited/components/topvisited/default.htm new file mode 100644 index 000000000..eb8c94e16 --- /dev/null +++ b/plugins/pollozen/mostvisited/components/topvisited/default.htm @@ -0,0 +1,18 @@ +{% set mostVisitedPosts = __SELF__.mostVisitedPosts %} +
+

Top Publications

+
+
    + {% for post in mostVisitedPosts %} +
  • +
    +
    +
    +

    {{post.title}}

    +
    +
    +
  • + {% endfor %} +
+
+
diff --git a/plugins/pollozen/mostvisited/models/Visits.php b/plugins/pollozen/mostvisited/models/Visits.php new file mode 100644 index 000000000..c25bdf364 --- /dev/null +++ b/plugins/pollozen/mostvisited/models/Visits.php @@ -0,0 +1,37 @@ + ['Rainlab\Blog\Models\Post'] + ]; +} \ No newline at end of file diff --git a/plugins/pollozen/mostvisited/models/visits/columns.yaml b/plugins/pollozen/mostvisited/models/visits/columns.yaml new file mode 100644 index 000000000..b11160b42 --- /dev/null +++ b/plugins/pollozen/mostvisited/models/visits/columns.yaml @@ -0,0 +1,8 @@ +# =================================== +# List Column Definitions +# =================================== + +columns: + id: + label: ID + searchable: true diff --git a/plugins/pollozen/mostvisited/models/visits/fields.yaml b/plugins/pollozen/mostvisited/models/visits/fields.yaml new file mode 100644 index 000000000..c611f31c7 --- /dev/null +++ b/plugins/pollozen/mostvisited/models/visits/fields.yaml @@ -0,0 +1,8 @@ +# =================================== +# Form Field Definitions +# =================================== + +fields: + id: + label: ID + disabled: true diff --git a/plugins/pollozen/mostvisited/updates/create_visits_table.php b/plugins/pollozen/mostvisited/updates/create_visits_table.php new file mode 100644 index 000000000..6ef416413 --- /dev/null +++ b/plugins/pollozen/mostvisited/updates/create_visits_table.php @@ -0,0 +1,27 @@ +engine = 'InnoDB'; + $table->increments('id'); + $table->integer('post_id')->unsigned(); + $table->date('date'); + $table->smallInteger('visits')->unsigned()->default(0); + $table->timestamps(); + }); + } + + public function down() + { + Schema::dropIfExists('pollozen_mostvisited_visits'); + } + +} diff --git a/plugins/pollozen/mostvisited/updates/version.yaml b/plugins/pollozen/mostvisited/updates/version.yaml new file mode 100644 index 000000000..c52463799 --- /dev/null +++ b/plugins/pollozen/mostvisited/updates/version.yaml @@ -0,0 +1,5 @@ +1.0.1: + - First version of MostVisited. Create the Visitis table + - create_visits_table.php +1.0.2: + - Improve a new query to get the top visited post. Same results in 4x faster diff --git a/plugins/vdomah/blogviews/LICENCE.md b/plugins/vdomah/blogviews/LICENCE.md new file mode 100644 index 000000000..38cee799e --- /dev/null +++ b/plugins/vdomah/blogviews/LICENCE.md @@ -0,0 +1,19 @@ +# MIT license + +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. diff --git a/plugins/vdomah/blogviews/Plugin.php b/plugins/vdomah/blogviews/Plugin.php new file mode 100644 index 000000000..541a80b1c --- /dev/null +++ b/plugins/vdomah/blogviews/Plugin.php @@ -0,0 +1,228 @@ + 'vdomah.blogviews::lang.plugin.name', + 'description' => 'vdomah.blogviews::lang.plugin.description', + 'author' => 'Art Gek', + 'icon' => 'icon-signal', + 'homepage' => 'https://github.com/vdomah/blogviews' + ]; + } + + /** + * Registers any front-end components implemented in this plugin. + * + * @return array + */ + public function registerComponents() + { + return [ + Views::class => 'views', + Popular::class => 'popularPosts' + ]; + } + + public function boot() + { + PostComponent::extend(function($component) { + if ($this->app->runningInBackend() || !Controller::getController()) { + return; + } + + $result = Event::fire(self::EVENT_BEFORE_TRACK, [$this, $component]); + + $preventTrack = isset($result[0][self::PARAM_TRACK_PREVENT]) && $result[0][self::PARAM_TRACK_PREVENT]; + + if ($preventTrack) + return; + + $trackBot = isset($result[0][self::PARAM_TRACK_BOT]) && $result[0][self::PARAM_TRACK_BOT]; + + if ($this->isBot() && !$trackBot) { + // do not do anything if a bot is detected + return; + } + + $post = $this->getPost($component); + + if (!is_null($post)) { + $this->track($post); + } + + return true; + }); + + PostModel::extend(function($model) { + $model->addDynamicMethod('getViewsAttribute', function() use ($model) { + $obj = Db::table('vdomah_blogviews_views') + ->where('post_id', $model->getKey()); + + $out = 0; + if ($obj->count() > 0) { + $out = $obj->first()->views; + } + + return $out; + }); + }); + } + + private function setViews($post, $views = null) + { + $obj = Db::table($this->table_views) + ->where('post_id', $post->getKey()); + + if ($obj->count() > 0) { + $row = $obj->first(); + if (!$views) { + $views = ++$row->views; + } + $obj->update(['views' => $views]); + } else { + if (!$views) { + $views = 1; + } + Db::table($this->table_views)->insert([ + 'post_id' => $post->getKey(), + 'views' => $views + ]); + } + } + + private function isBot() + { + $is_bot = false; + + if (isset($_SERVER['HTTP_USER_AGENT'])) { + $botParser = new BotParser(); + $botParser->setUserAgent($_SERVER['HTTP_USER_AGENT']); + $botParser->discardDetails(); + + $is_bot = $botParser->parse(); + } + + return $is_bot; + } + + /* + * Getting slug value using logic from Cms\Classes\Controller setComponentPropertiesFromParams + * + * @return PostModel + */ + private function getPost($component) + { + $slugValue = $component->property('slug'); + $routerParameters = Controller::getController()->getRouter()->getParameters(); + + $slugValueFromUrl = null; + + if (preg_match('/^\{\{([^\}]+)\}\}$/', $slugValue, $matches)) { + $paramName = trim($matches[1]); + + if (substr($paramName, 0, 1) == ':') { + $routeParamName = substr($paramName, 1); + $slugValueFromUrl = array_key_exists($routeParamName, $routerParameters) + ? $routerParameters[$routeParamName] + : null; + + } + } + + if (!$slugValueFromUrl) + return null; + + $post = PostModel::whereSlug($slugValueFromUrl)->first(); + + return $post; + } + + private function track($post) + { + if (Settings::get('double_tracking_prevent_method', 'cookie') == 'session') { + $this->setViewsSession($post); + } else { + $this->setViewsCookie($post); + } + } + + private function setViewsSession($post) + { + if (!Session::has(self::POST_VIEWED)) { + Session::put(self::POST_VIEWED, []); + } + + if (!in_array($post->getKey(), Session::get(self::POST_VIEWED))) { + $this->setViews($post); + + Session::push(self::POST_VIEWED, $post->getKey()); + } + } + + private function setViewsCookie($post) + { + $cookName = self::POST_VIEWED . '-' . $post->getKey(); + + if (Cookie::get( $cookName, 0 ) == 0) { + $this->setViews($post); + + Cookie::queue( $cookName, '1', 525000 ); + } + } + + public function registerSettings() + { + return [ + 'config' => [ + 'label' => 'vdomah.blogviews::lang.plugin.name', + 'description' => 'vdomah.blogviews::lang.plugin.description_settings', + 'category' => 'rainlab.blog::lang.blog.menu_label', + 'icon' => 'icon-signal', + 'class' => Settings::class, + 'order' => 501, + 'permissions' => [ + 'blogviews-menu-settings', + ], + ], + ]; + } +} diff --git a/plugins/vdomah/blogviews/README.md b/plugins/vdomah/blogviews/README.md new file mode 100644 index 000000000..52bf2e9a6 --- /dev/null +++ b/plugins/vdomah/blogviews/README.md @@ -0,0 +1,15 @@ +# Blog Views Extension +This plugin is an extension to the [RainLab.Blog](https://github.com/rainlab/blog-plugin) plugin. This extension add views tracking to blog posts and allows to add views counter to a post and display popular posts widget. + +Adds dynamic views property to Post model: {{ post.views }} + +### Components +#### Popular Posts +The `popularPosts` component can be used to display top viewed posts. + +- **postsLimit** - The max number of posts to show. +- **postPage** - Reference to the page name for linking to posts. +- **noPostsMessage** - Message to display when there are no posts. + +#### Views (counter) +The `Views` component can be used to display post views number. In most cases use just {{ post.views }} without this component. \ No newline at end of file diff --git a/plugins/vdomah/blogviews/components/Popular.php b/plugins/vdomah/blogviews/components/Popular.php new file mode 100644 index 000000000..e891d4080 --- /dev/null +++ b/plugins/vdomah/blogviews/components/Popular.php @@ -0,0 +1,141 @@ + 'vdomah.blogviews::lang.component.popular_name', + 'description' => 'vdomah.blogviews::lang.component.popular_description' + ]; + } + + public function defineProperties() + { + return [ + 'category' => [ + 'title' => 'vdomah.blogviews::lang.properties.category', + 'type' => 'dropdown', + 'default' => '{{ :category }}', + ], + 'postsLimit' => [ + 'title' => 'vdomah.blogviews::lang.properties.posts_limit', + 'type' => 'string', + 'validationPattern' => '^[0-9]+$', + 'validationMessage' => 'vdomah.blogviews::lang.properties.posts_limit_validation', + 'default' => '3', + ], + 'noPostsMessage' => [ + 'title' => 'vdomah.blogviews::lang.properties.posts_no_posts', + 'description' => 'vdomah.blogviews::lang.properties.posts_no_posts_description', + 'type' => 'string', + 'default' => 'No posts found', + 'showExternalParam' => false + ], + 'postPage' => [ + 'title' => 'vdomah.blogviews::lang.properties.posts_post', + 'description' => 'vdomah.blogviews::lang.properties.posts_post_description', + 'type' => 'dropdown', + 'default' => 'blog/post', + 'group' => 'Links', + ], + ]; + } + + public function getCategoryOptions() + { + return array_merge( + [ + null => e(trans('vdomah.blogviews::lang.properties.all_option')), + 0 => e(trans('vdomah.blogviews::lang.properties.no_option')) + ], + BlogCategory::lists('name', 'slug') + ); + } + + public function onRun() + { + $this->prepareVars(); + + $this->posts = $this->page['posts'] = $this->listPosts(); + } + + protected function listPosts() + { + /* + * List all the posts + */ + $query = BlogPost::isPublished() + ->leftJoin('vdomah_blogviews_views as pv', 'pv.post_id', '=', 'rainlab_blog_posts.id') + ; + + $category_slug = $this->property('category'); + if ((is_string($category_slug) && strlen($category_slug) == 0) || $category_slug === false) + $category_slug = null; + + if ($category_slug !== null) { + if ($category_slug == 0) + $query = $query->has('categories', '=', 0); + elseif ($category_slug > 0) + $query->whereHas('categories', function($q) use ($category_slug) { + $q->where('slug', $category_slug); + }); + } + + $query = $query->orderBy('views', 'DESC') + ->limit($this->postsLimit) + ; + + $posts = $query->get(); + + $posts->each(function($post) { + $post->setUrl($this->postPage, $this->controller); + }); + + return $posts; + } + + protected function prepareVars() + { + $this->postsLimit = $this->page['postsLimit'] = $this->property('postsLimit'); + $this->noPostsMessage = $this->page['noPostsMessage'] = $this->property('noPostsMessage'); + + /* + * Page links + */ + $this->postPage = $this->page['postPage'] = $this->property('postPage'); + } + + public function getPostPageOptions() + { + return Page::sortBy('baseFileName')->lists('baseFileName', 'baseFileName'); + } +} diff --git a/plugins/vdomah/blogviews/components/Views.php b/plugins/vdomah/blogviews/components/Views.php new file mode 100644 index 000000000..497b90688 --- /dev/null +++ b/plugins/vdomah/blogviews/components/Views.php @@ -0,0 +1,63 @@ + 'vdomah.blogviews::lang.component.views_name', + 'description' => 'vdomah.blogviews::lang.component.views_description' + ]; + } + + public function defineProperties() + { + return [ + 'slug' => [ + 'title' => 'rainlab.blog::lang.properties.post_slug', + 'description' => 'rainlab.blog::lang.properties.post_slug_description', + 'default' => '{{ :slug }}', + 'type' => 'string' + ] + ]; + } + + public function onRun() + { + $this->views = $this->page['views'] = $this->getViews(); + } + + protected function loadPost() + { + $slug = $this->property('slug'); + $post = BlogPost::isPublished()->where('slug', $slug)->first(); + + return $post; + } + + protected function getViews() + { + $out = 0; + $post = $this->loadPost(); + + if(!is_null($post)) { + $obj = Db::table('vdomah_blogviews_views') + ->where('post_id', $post->getKey()); + + if ($obj->count() > 0) { + $out = $obj->first()->views; + } + } + + return $out; + } +} diff --git a/plugins/vdomah/blogviews/components/popular/default.htm b/plugins/vdomah/blogviews/components/popular/default.htm new file mode 100644 index 000000000..cdae49241 --- /dev/null +++ b/plugins/vdomah/blogviews/components/popular/default.htm @@ -0,0 +1,12 @@ +{% set posts = __SELF__.posts %} + + \ No newline at end of file diff --git a/plugins/vdomah/blogviews/components/views/default.htm b/plugins/vdomah/blogviews/components/views/default.htm new file mode 100644 index 000000000..dbc671e6f --- /dev/null +++ b/plugins/vdomah/blogviews/components/views/default.htm @@ -0,0 +1,3 @@ +{% set post = __SELF__.post %} + +Views: {{ views }} \ No newline at end of file diff --git a/plugins/vdomah/blogviews/lang/en/lang.php b/plugins/vdomah/blogviews/lang/en/lang.php new file mode 100644 index 000000000..e4fa2ec68 --- /dev/null +++ b/plugins/vdomah/blogviews/lang/en/lang.php @@ -0,0 +1,35 @@ + [ + 'name' => 'Blog Views', + 'description' => 'The plugin enables blog posts views tracking and displaying popular articles.', + 'description_settings' => 'Blog Views tracking settings', + ], + 'properties' => [ + 'category' => 'Category', + 'all_option' => '- All categories -', + 'no_option' => '- With no category -', + 'posts_limit' => 'Limit', + 'posts_limit_validation' => 'Invalid format of the limit value', + 'posts_no_posts' => 'No posts message', + 'posts_no_posts_description' => 'Message to display in the blog post popular list in case if there are no posts. This property is used by the default component partial.', + 'posts_post' => 'Post page', + 'posts_post_description' => 'Name of the blog post page file for the "Learn more" links. This property is used by the default component partial.' + ], + 'post' => [ + 'tab_views' => 'Views' + ], + 'component' => [ + 'popular_name' => 'Popular Posts', + 'popular_description' => 'Most viewed posts list', + 'views_name' => 'Post Views', + 'views_description' => 'Show post views' + ], + 'settings' => [ + 'double_tracking_prevent_method' => 'Double tracking prevent method', + 'double_tracking_prevent_method_comment' => 'What method to use to store user\'s id. For preventing tracking his visit multiple times', + 'cookie' => 'Cookie', + 'session' => 'Session', + ], +]; diff --git a/plugins/vdomah/blogviews/models/Settings.php b/plugins/vdomah/blogviews/models/Settings.php new file mode 100644 index 000000000..da3cdc9bb --- /dev/null +++ b/plugins/vdomah/blogviews/models/Settings.php @@ -0,0 +1,12 @@ +engine = 'InnoDB'; + $table->integer('views'); + $table->integer('post_id')->unsigned()->nullable()->index(); + $table->primary(array('post_id')); + }); + } + + public function down() + { + Schema::dropIfExists('vdomah_blogviews_views'); + } +} diff --git a/plugins/vdomah/blogviews/updates/version.yaml b/plugins/vdomah/blogviews/updates/version.yaml new file mode 100644 index 000000000..59b648318 --- /dev/null +++ b/plugins/vdomah/blogviews/updates/version.yaml @@ -0,0 +1,31 @@ +1.0.0: + - First version of BlogViews + - create_post_views_table.php +1.0.1: + - Limit and link params fixed +1.0.2: + - Added 'views' dynamic property to Post model +1.0.3: + - Improve the translation. Add MIT license. Pull request by gergo85 +1.0.4: + - Default value to 0 in getViewsAttribute (thanks to hambern) +1.0.5: + - Add support for whatever slug url name parameter like {{ :slug_some_custom_url_parameter }} +1.0.6: + - Ability to choose blog category for Popular posts +1.0.7: + - Dynamic category slug url parameter. Only published posts in Popular component +1.0.8: + - "Fixed error using blogviews with sitemap: check if Controller instantiated before extend" +1.0.9: + - "Get url parameters directly from Controller instance without component. Using Cookie instead of Session" +1.0.10: + - "Fix bug when post is not found." +1.0.11: + - Don't count web crawler bots visits. +1.0.12: + - "blogviews.before.track added with trackPrevent and trackBot options." +1.0.13: + - "Both Cookie and Session methods available to prevent doubletracking" +1.0.14: + - "Fix: bot detection if no HTTP_USER_AGENT is present in request" \ No newline at end of file diff --git a/plugins/vdomah/blogviews/vendor/autoload.php b/plugins/vdomah/blogviews/vendor/autoload.php new file mode 100644 index 000000000..5ce481459 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/autoload.php @@ -0,0 +1,7 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + // PSR-4 + private $prefixLengthsPsr4 = array(); + private $prefixDirsPsr4 = array(); + private $fallbackDirsPsr4 = array(); + + // PSR-0 + private $prefixesPsr0 = array(); + private $fallbackDirsPsr0 = array(); + + private $useIncludePath = false; + private $classMap = array(); + private $classMapAuthoritative = false; + private $missingClasses = array(); + private $apcuPrefix; + + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', $this->prefixesPsr0); + } + + return array(); + } + + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 base directories + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + */ +function includeFile($file) +{ + include $file; +} diff --git a/plugins/vdomah/blogviews/vendor/composer/LICENSE b/plugins/vdomah/blogviews/vendor/composer/LICENSE new file mode 100644 index 000000000..f27399a04 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +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. + diff --git a/plugins/vdomah/blogviews/vendor/composer/autoload_classmap.php b/plugins/vdomah/blogviews/vendor/composer/autoload_classmap.php new file mode 100644 index 000000000..7a91153b0 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/composer/autoload_classmap.php @@ -0,0 +1,9 @@ + $vendorDir . '/mustangostang/spyc/Spyc.php', +); diff --git a/plugins/vdomah/blogviews/vendor/composer/autoload_namespaces.php b/plugins/vdomah/blogviews/vendor/composer/autoload_namespaces.php new file mode 100644 index 000000000..b7fc0125d --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ + array($vendorDir . '/piwik/device-detector'), +); diff --git a/plugins/vdomah/blogviews/vendor/composer/autoload_real.php b/plugins/vdomah/blogviews/vendor/composer/autoload_real.php new file mode 100644 index 000000000..757420f1e --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/composer/autoload_real.php @@ -0,0 +1,70 @@ += 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require_once __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInit71a0c07406b6d528b5494257df58789c::getInitializer($loader)); + } else { + $map = require __DIR__ . '/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + $loader->set($namespace, $path); + } + + $map = require __DIR__ . '/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + $loader->setPsr4($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->register(true); + + if ($useStaticLoader) { + $includeFiles = Composer\Autoload\ComposerStaticInit71a0c07406b6d528b5494257df58789c::$files; + } else { + $includeFiles = require __DIR__ . '/autoload_files.php'; + } + foreach ($includeFiles as $fileIdentifier => $file) { + composerRequire71a0c07406b6d528b5494257df58789c($fileIdentifier, $file); + } + + return $loader; + } +} + +function composerRequire71a0c07406b6d528b5494257df58789c($fileIdentifier, $file) +{ + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + require $file; + + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + } +} diff --git a/plugins/vdomah/blogviews/vendor/composer/autoload_static.php b/plugins/vdomah/blogviews/vendor/composer/autoload_static.php new file mode 100644 index 000000000..0490450d9 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/composer/autoload_static.php @@ -0,0 +1,35 @@ + __DIR__ . '/..' . '/mustangostang/spyc/Spyc.php', + ); + + public static $prefixLengthsPsr4 = array ( + 'D' => + array ( + 'DeviceDetector\\' => 15, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'DeviceDetector\\' => + array ( + 0 => __DIR__ . '/..' . '/piwik/device-detector', + ), + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInit71a0c07406b6d528b5494257df58789c::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit71a0c07406b6d528b5494257df58789c::$prefixDirsPsr4; + + }, null, ClassLoader::class); + } +} diff --git a/plugins/vdomah/blogviews/vendor/composer/installed.json b/plugins/vdomah/blogviews/vendor/composer/installed.json new file mode 100644 index 000000000..af8867c75 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/composer/installed.json @@ -0,0 +1,111 @@ +[ + { + "name": "mustangostang/spyc", + "version": "0.6.3", + "version_normalized": "0.6.3.0", + "source": { + "type": "git", + "url": "git@github.com:mustangostang/spyc.git", + "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mustangostang/spyc/zipball/4627c838b16550b666d15aeae1e5289dd5b77da0", + "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0", + "shasum": "" + }, + "require": { + "php": ">=5.3.1" + }, + "require-dev": { + "phpunit/phpunit": "4.3.*@dev" + }, + "time": "2019-09-10T13:16:29+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.5.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "Spyc.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "mustangostang", + "email": "vlad.andersen@gmail.com" + } + ], + "description": "A simple YAML loader/dumper class for PHP", + "homepage": "https://github.com/mustangostang/spyc/", + "keywords": [ + "spyc", + "yaml", + "yml" + ] + }, + { + "name": "piwik/device-detector", + "version": "3.12.4", + "version_normalized": "3.12.4.0", + "source": { + "type": "git", + "url": "https://github.com/matomo-org/device-detector.git", + "reference": "6a92e45a55eb507f53581e9add7dc82835ad6424" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/matomo-org/device-detector/zipball/6a92e45a55eb507f53581e9add7dc82835ad6424", + "reference": "6a92e45a55eb507f53581e9add7dc82835ad6424", + "shasum": "" + }, + "require": { + "mustangostang/spyc": "*", + "php": ">=5.5" + }, + "require-dev": { + "fabpot/php-cs-fixer": "~1.7", + "matthiasmullie/scrapbook": "@stable", + "phpunit/phpunit": "^4.8.36", + "psr/cache": "^1.0", + "psr/simple-cache": "^1.0" + }, + "suggest": { + "doctrine/cache": "Can directly be used for caching purpose", + "ext-yaml": "Necessary for using the Pecl YAML parser" + }, + "time": "2020-03-31T08:53:12+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "DeviceDetector\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "The Matomo Team", + "email": "hello@matomo.org", + "homepage": "https://matomo.org/team/" + } + ], + "description": "The Universal Device Detection library, that parses User Agents and detects devices (desktop, tablet, mobile, tv, cars, console, etc.), clients (browsers, media players, mobile apps, feed readers, libraries, etc), operating systems, devices, brands and models.", + "homepage": "https://matomo.org", + "keywords": [ + "devicedetection", + "parser", + "useragent" + ] + } +] diff --git a/plugins/vdomah/blogviews/vendor/mustangostang/spyc/COPYING b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/COPYING new file mode 100644 index 000000000..8e7ddbcf6 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/COPYING @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2011 Vladimir Andersen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/plugins/vdomah/blogviews/vendor/mustangostang/spyc/README.md b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/README.md new file mode 100644 index 000000000..1ebbdc556 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/README.md @@ -0,0 +1,30 @@ +**Spyc** is a YAML loader/dumper written in pure PHP. Given a YAML document, Spyc will return an array that +you can use however you see fit. Given an array, Spyc will return a string which contains a YAML document +built from your data. + +**YAML** is an amazingly human friendly and strikingly versatile data serialization language which can be used +for log files, config files, custom protocols, the works. For more information, see http://www.yaml.org. + +Spyc supports YAML 1.0 specification. + +## Using Spyc + +Using Spyc is trivial: + +```php + + * @author Chris Wanstrath + * @link https://github.com/mustangostang/spyc/ + * @copyright Copyright 2005-2006 Chris Wanstrath, 2006-2011 Vlad Andersen + * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @package Spyc + */ + +if (!function_exists('spyc_load')) { + /** + * Parses YAML to array. + * @param string $string YAML string. + * @return array + */ + function spyc_load ($string) { + return Spyc::YAMLLoadString($string); + } +} + +if (!function_exists('spyc_load_file')) { + /** + * Parses YAML to array. + * @param string $file Path to YAML file. + * @return array + */ + function spyc_load_file ($file) { + return Spyc::YAMLLoad($file); + } +} + +if (!function_exists('spyc_dump')) { + /** + * Dumps array to YAML. + * @param array $data Array. + * @return string + */ + function spyc_dump ($data) { + return Spyc::YAMLDump($data, false, false, true); + } +} + +if (!class_exists('Spyc')) { + +/** + * The Simple PHP YAML Class. + * + * This class can be used to read a YAML file and convert its contents + * into a PHP array. It currently supports a very limited subsection of + * the YAML spec. + * + * Usage: + * + * $Spyc = new Spyc; + * $array = $Spyc->load($file); + * + * or: + * + * $array = Spyc::YAMLLoad($file); + * + * or: + * + * $array = spyc_load_file($file); + * + * @package Spyc + */ +class Spyc { + + // SETTINGS + + const REMPTY = "\0\0\0\0\0"; + + /** + * Setting this to true will force YAMLDump to enclose any string value in + * quotes. False by default. + * + * @var bool + */ + public $setting_dump_force_quotes = false; + + /** + * Setting this to true will forse YAMLLoad to use syck_load function when + * possible. False by default. + * @var bool + */ + public $setting_use_syck_is_possible = false; + + /** + * Setting this to true will forse YAMLLoad to use syck_load function when + * possible. False by default. + * @var bool + */ + public $setting_empty_hash_as_object = false; + + + /**#@+ + * @access private + * @var mixed + */ + private $_dumpIndent; + private $_dumpWordWrap; + private $_containsGroupAnchor = false; + private $_containsGroupAlias = false; + private $path; + private $result; + private $LiteralPlaceHolder = '___YAML_Literal_Block___'; + private $SavedGroups = array(); + private $indent; + /** + * Path modifier that should be applied after adding current element. + * @var array + */ + private $delayedPath = array(); + + /**#@+ + * @access public + * @var mixed + */ + public $_nodeId; + +/** + * Load a valid YAML string to Spyc. + * @param string $input + * @return array + */ + public function load ($input) { + return $this->_loadString($input); + } + + /** + * Load a valid YAML file to Spyc. + * @param string $file + * @return array + */ + public function loadFile ($file) { + return $this->_load($file); + } + + /** + * Load YAML into a PHP array statically + * + * The load method, when supplied with a YAML stream (string or file), + * will do its best to convert YAML in a file into a PHP array. Pretty + * simple. + * Usage: + * + * $array = Spyc::YAMLLoad('lucky.yaml'); + * print_r($array); + * + * @access public + * @return array + * @param string $input Path of YAML file or string containing YAML + * @param array set options + */ + public static function YAMLLoad($input, $options = []) { + $Spyc = new Spyc; + foreach ($options as $key => $value) { + if (property_exists($Spyc, $key)) { + $Spyc->$key = $value; + } + } + return $Spyc->_load($input); + } + + /** + * Load a string of YAML into a PHP array statically + * + * The load method, when supplied with a YAML string, will do its best + * to convert YAML in a string into a PHP array. Pretty simple. + * + * Note: use this function if you don't want files from the file system + * loaded and processed as YAML. This is of interest to people concerned + * about security whose input is from a string. + * + * Usage: + * + * $array = Spyc::YAMLLoadString("---\n0: hello world\n"); + * print_r($array); + * + * @access public + * @return array + * @param string $input String containing YAML + * @param array set options + */ + public static function YAMLLoadString($input, $options = []) { + $Spyc = new Spyc; + foreach ($options as $key => $value) { + if (property_exists($Spyc, $key)) { + $Spyc->$key = $value; + } + } + return $Spyc->_loadString($input); + } + + /** + * Dump YAML from PHP array statically + * + * The dump method, when supplied with an array, will do its best + * to convert the array into friendly YAML. Pretty simple. Feel free to + * save the returned string as nothing.yaml and pass it around. + * + * Oh, and you can decide how big the indent is and what the wordwrap + * for folding is. Pretty cool -- just pass in 'false' for either if + * you want to use the default. + * + * Indent's default is 2 spaces, wordwrap's default is 40 characters. And + * you can turn off wordwrap by passing in 0. + * + * @access public + * @return string + * @param array|\stdClass $array PHP array + * @param int $indent Pass in false to use the default, which is 2 + * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40) + * @param bool $no_opening_dashes Do not start YAML file with "---\n" + */ + public static function YAMLDump($array, $indent = false, $wordwrap = false, $no_opening_dashes = false) { + $spyc = new Spyc; + return $spyc->dump($array, $indent, $wordwrap, $no_opening_dashes); + } + + + /** + * Dump PHP array to YAML + * + * The dump method, when supplied with an array, will do its best + * to convert the array into friendly YAML. Pretty simple. Feel free to + * save the returned string as tasteful.yaml and pass it around. + * + * Oh, and you can decide how big the indent is and what the wordwrap + * for folding is. Pretty cool -- just pass in 'false' for either if + * you want to use the default. + * + * Indent's default is 2 spaces, wordwrap's default is 40 characters. And + * you can turn off wordwrap by passing in 0. + * + * @access public + * @return string + * @param array $array PHP array + * @param int $indent Pass in false to use the default, which is 2 + * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40) + */ + public function dump($array,$indent = false,$wordwrap = false, $no_opening_dashes = false) { + // Dumps to some very clean YAML. We'll have to add some more features + // and options soon. And better support for folding. + + // New features and options. + if ($indent === false or !is_numeric($indent)) { + $this->_dumpIndent = 2; + } else { + $this->_dumpIndent = $indent; + } + + if ($wordwrap === false or !is_numeric($wordwrap)) { + $this->_dumpWordWrap = 40; + } else { + $this->_dumpWordWrap = $wordwrap; + } + + // New YAML document + $string = ""; + if (!$no_opening_dashes) $string = "---\n"; + + // Start at the base of the array and move through it. + if ($array) { + $array = (array)$array; + $previous_key = -1; + foreach ($array as $key => $value) { + if (!isset($first_key)) $first_key = $key; + $string .= $this->_yamlize($key,$value,0,$previous_key, $first_key, $array); + $previous_key = $key; + } + } + return $string; + } + + /** + * Attempts to convert a key / value array item to YAML + * @access private + * @return string + * @param $key The name of the key + * @param $value The value of the item + * @param $indent The indent of the current node + */ + private function _yamlize($key,$value,$indent, $previous_key = -1, $first_key = 0, $source_array = null) { + if(is_object($value)) $value = (array)$value; + if (is_array($value)) { + if (empty ($value)) + return $this->_dumpNode($key, array(), $indent, $previous_key, $first_key, $source_array); + // It has children. What to do? + // Make it the right kind of item + $string = $this->_dumpNode($key, self::REMPTY, $indent, $previous_key, $first_key, $source_array); + // Add the indent + $indent += $this->_dumpIndent; + // Yamlize the array + $string .= $this->_yamlizeArray($value,$indent); + } elseif (!is_array($value)) { + // It doesn't have children. Yip. + $string = $this->_dumpNode($key, $value, $indent, $previous_key, $first_key, $source_array); + } + return $string; + } + + /** + * Attempts to convert an array to YAML + * @access private + * @return string + * @param $array The array you want to convert + * @param $indent The indent of the current level + */ + private function _yamlizeArray($array,$indent) { + if (is_array($array)) { + $string = ''; + $previous_key = -1; + foreach ($array as $key => $value) { + if (!isset($first_key)) $first_key = $key; + $string .= $this->_yamlize($key, $value, $indent, $previous_key, $first_key, $array); + $previous_key = $key; + } + return $string; + } else { + return false; + } + } + + /** + * Returns YAML from a key and a value + * @access private + * @return string + * @param $key The name of the key + * @param $value The value of the item + * @param $indent The indent of the current node + */ + private function _dumpNode($key, $value, $indent, $previous_key = -1, $first_key = 0, $source_array = null) { + // do some folding here, for blocks + if (is_string ($value) && ((strpos($value,"\n") !== false || strpos($value,": ") !== false || strpos($value,"- ") !== false || + strpos($value,"*") !== false || strpos($value,"#") !== false || strpos($value,"<") !== false || strpos($value,">") !== false || strpos ($value, '%') !== false || strpos ($value, ' ') !== false || + strpos($value,"[") !== false || strpos($value,"]") !== false || strpos($value,"{") !== false || strpos($value,"}") !== false) || strpos($value,"&") !== false || strpos($value, "'") !== false || strpos($value, "!") === 0 || + substr ($value, -1, 1) == ':') + ) { + $value = $this->_doLiteralBlock($value,$indent); + } else { + $value = $this->_doFolding($value,$indent); + } + + if ($value === array()) $value = '[ ]'; + if ($value === "") $value = '""'; + if (self::isTranslationWord($value)) { + $value = $this->_doLiteralBlock($value, $indent); + } + if (trim ($value) != $value) + $value = $this->_doLiteralBlock($value,$indent); + + if (is_bool($value)) { + $value = $value ? "true" : "false"; + } + + if ($value === null) $value = 'null'; + if ($value === "'" . self::REMPTY . "'") $value = null; + + $spaces = str_repeat(' ',$indent); + + //if (is_int($key) && $key - 1 == $previous_key && $first_key===0) { + if (is_array ($source_array) && array_keys($source_array) === range(0, count($source_array) - 1)) { + // It's a sequence + $string = $spaces.'- '.$value."\n"; + } else { + // if ($first_key===0) throw new Exception('Keys are all screwy. The first one was zero, now it\'s "'. $key .'"'); + // It's mapped + if (strpos($key, ":") !== false || strpos($key, "#") !== false) { $key = '"' . $key . '"'; } + $string = rtrim ($spaces.$key.': '.$value)."\n"; + } + return $string; + } + + /** + * Creates a literal block for dumping + * @access private + * @return string + * @param $value + * @param $indent int The value of the indent + */ + private function _doLiteralBlock($value,$indent) { + if ($value === "\n") return '\n'; + if (strpos($value, "\n") === false && strpos($value, "'") === false) { + return sprintf ("'%s'", $value); + } + if (strpos($value, "\n") === false && strpos($value, '"') === false) { + return sprintf ('"%s"', $value); + } + $exploded = explode("\n",$value); + $newValue = '|'; + if (isset($exploded[0]) && ($exploded[0] == "|" || $exploded[0] == "|-" || $exploded[0] == ">")) { + $newValue = $exploded[0]; + unset($exploded[0]); + } + $indent += $this->_dumpIndent; + $spaces = str_repeat(' ',$indent); + foreach ($exploded as $line) { + $line = trim($line); + if (strpos($line, '"') === 0 && strrpos($line, '"') == (strlen($line)-1) || strpos($line, "'") === 0 && strrpos($line, "'") == (strlen($line)-1)) { + $line = substr($line, 1, -1); + } + $newValue .= "\n" . $spaces . ($line); + } + return $newValue; + } + + /** + * Folds a string of text, if necessary + * @access private + * @return string + * @param $value The string you wish to fold + */ + private function _doFolding($value,$indent) { + // Don't do anything if wordwrap is set to 0 + + if ($this->_dumpWordWrap !== 0 && is_string ($value) && strlen($value) > $this->_dumpWordWrap) { + $indent += $this->_dumpIndent; + $indent = str_repeat(' ',$indent); + $wrapped = wordwrap($value,$this->_dumpWordWrap,"\n$indent"); + $value = ">\n".$indent.$wrapped; + } else { + if ($this->setting_dump_force_quotes && is_string ($value) && $value !== self::REMPTY) + $value = '"' . $value . '"'; + if (is_numeric($value) && is_string($value)) + $value = '"' . $value . '"'; + } + + + return $value; + } + + private function isTrueWord($value) { + $words = self::getTranslations(array('true', 'on', 'yes', 'y')); + return in_array($value, $words, true); + } + + private function isFalseWord($value) { + $words = self::getTranslations(array('false', 'off', 'no', 'n')); + return in_array($value, $words, true); + } + + private function isNullWord($value) { + $words = self::getTranslations(array('null', '~')); + return in_array($value, $words, true); + } + + private function isTranslationWord($value) { + return ( + self::isTrueWord($value) || + self::isFalseWord($value) || + self::isNullWord($value) + ); + } + + /** + * Coerce a string into a native type + * Reference: http://yaml.org/type/bool.html + * TODO: Use only words from the YAML spec. + * @access private + * @param $value The value to coerce + */ + private function coerceValue(&$value) { + if (self::isTrueWord($value)) { + $value = true; + } else if (self::isFalseWord($value)) { + $value = false; + } else if (self::isNullWord($value)) { + $value = null; + } + } + + /** + * Given a set of words, perform the appropriate translations on them to + * match the YAML 1.1 specification for type coercing. + * @param $words The words to translate + * @access private + */ + private static function getTranslations(array $words) { + $result = array(); + foreach ($words as $i) { + $result = array_merge($result, array(ucfirst($i), strtoupper($i), strtolower($i))); + } + return $result; + } + +// LOADING FUNCTIONS + + private function _load($input) { + $Source = $this->loadFromSource($input); + return $this->loadWithSource($Source); + } + + private function _loadString($input) { + $Source = $this->loadFromString($input); + return $this->loadWithSource($Source); + } + + private function loadWithSource($Source) { + if (empty ($Source)) return array(); + if ($this->setting_use_syck_is_possible && function_exists ('syck_load')) { + $array = syck_load (implode ("\n", $Source)); + return is_array($array) ? $array : array(); + } + + $this->path = array(); + $this->result = array(); + + $cnt = count($Source); + for ($i = 0; $i < $cnt; $i++) { + $line = $Source[$i]; + + $this->indent = strlen($line) - strlen(ltrim($line)); + $tempPath = $this->getParentPathByIndent($this->indent); + $line = self::stripIndent($line, $this->indent); + if (self::isComment($line)) continue; + if (self::isEmpty($line)) continue; + $this->path = $tempPath; + + $literalBlockStyle = self::startsLiteralBlock($line); + if ($literalBlockStyle) { + $line = rtrim ($line, $literalBlockStyle . " \n"); + $literalBlock = ''; + $line .= ' '.$this->LiteralPlaceHolder; + $literal_block_indent = strlen($Source[$i+1]) - strlen(ltrim($Source[$i+1])); + while (++$i < $cnt && $this->literalBlockContinues($Source[$i], $this->indent)) { + $literalBlock = $this->addLiteralLine($literalBlock, $Source[$i], $literalBlockStyle, $literal_block_indent); + } + $i--; + } + + // Strip out comments + if (strpos ($line, '#')) { + $line = preg_replace('/\s*#([^"\']+)$/','',$line); + } + + while (++$i < $cnt && self::greedilyNeedNextLine($line)) { + $line = rtrim ($line, " \n\t\r") . ' ' . ltrim ($Source[$i], " \t"); + } + $i--; + + $lineArray = $this->_parseLine($line); + + if ($literalBlockStyle) + $lineArray = $this->revertLiteralPlaceHolder ($lineArray, $literalBlock); + + $this->addArray($lineArray, $this->indent); + + foreach ($this->delayedPath as $indent => $delayedPath) + $this->path[$indent] = $delayedPath; + + $this->delayedPath = array(); + + } + return $this->result; + } + + private function loadFromSource ($input) { + if (!empty($input) && strpos($input, "\n") === false && file_exists($input)) + $input = file_get_contents($input); + + return $this->loadFromString($input); + } + + private function loadFromString ($input) { + $lines = explode("\n",$input); + foreach ($lines as $k => $_) { + $lines[$k] = rtrim ($_, "\r"); + } + return $lines; + } + + /** + * Parses YAML code and returns an array for a node + * @access private + * @return array + * @param string $line A line from the YAML file + */ + private function _parseLine($line) { + if (!$line) return array(); + $line = trim($line); + if (!$line) return array(); + + $array = array(); + + $group = $this->nodeContainsGroup($line); + if ($group) { + $this->addGroup($line, $group); + $line = $this->stripGroup ($line, $group); + } + + if ($this->startsMappedSequence($line)) { + return $this->returnMappedSequence($line); + } + + if ($this->startsMappedValue($line)) { + return $this->returnMappedValue($line); + } + + if ($this->isArrayElement($line)) + return $this->returnArrayElement($line); + + if ($this->isPlainArray($line)) + return $this->returnPlainArray($line); + + return $this->returnKeyValuePair($line); + + } + + /** + * Finds the type of the passed value, returns the value as the new type. + * @access private + * @param string $value + * @return mixed + */ + private function _toType($value) { + if ($value === '') return ""; + + if ($this->setting_empty_hash_as_object && $value === '{}') { + return new stdClass(); + } + + $first_character = $value[0]; + $last_character = substr($value, -1, 1); + + $is_quoted = false; + do { + if (!$value) break; + if ($first_character != '"' && $first_character != "'") break; + if ($last_character != '"' && $last_character != "'") break; + $is_quoted = true; + } while (0); + + if ($is_quoted) { + $value = str_replace('\n', "\n", $value); + if ($first_character == "'") + return strtr(substr ($value, 1, -1), array ('\'\'' => '\'', '\\\''=> '\'')); + return strtr(substr ($value, 1, -1), array ('\\"' => '"', '\\\''=> '\'')); + } + + if (strpos($value, ' #') !== false && !$is_quoted) + $value = preg_replace('/\s+#(.+)$/','',$value); + + if ($first_character == '[' && $last_character == ']') { + // Take out strings sequences and mappings + $innerValue = trim(substr ($value, 1, -1)); + if ($innerValue === '') return array(); + $explode = $this->_inlineEscape($innerValue); + // Propagate value array + $value = array(); + foreach ($explode as $v) { + $value[] = $this->_toType($v); + } + return $value; + } + + if (strpos($value,': ')!==false && $first_character != '{') { + $array = explode(': ',$value); + $key = trim($array[0]); + array_shift($array); + $value = trim(implode(': ',$array)); + $value = $this->_toType($value); + return array($key => $value); + } + + if ($first_character == '{' && $last_character == '}') { + $innerValue = trim(substr ($value, 1, -1)); + if ($innerValue === '') return array(); + // Inline Mapping + // Take out strings sequences and mappings + $explode = $this->_inlineEscape($innerValue); + // Propagate value array + $array = array(); + foreach ($explode as $v) { + $SubArr = $this->_toType($v); + if (empty($SubArr)) continue; + if (is_array ($SubArr)) { + $array[key($SubArr)] = $SubArr[key($SubArr)]; continue; + } + $array[] = $SubArr; + } + return $array; + } + + if ($value == 'null' || $value == 'NULL' || $value == 'Null' || $value == '' || $value == '~') { + return null; + } + + if ( is_numeric($value) && preg_match ('/^(-|)[1-9]+[0-9]*$/', $value) ){ + $intvalue = (int)$value; + if ($intvalue != PHP_INT_MAX && $intvalue != ~PHP_INT_MAX) + $value = $intvalue; + return $value; + } + + if ( is_string($value) && preg_match('/^0[xX][0-9a-fA-F]+$/', $value)) { + // Hexadecimal value. + return hexdec($value); + } + + $this->coerceValue($value); + + if (is_numeric($value)) { + if ($value === '0') return 0; + if (rtrim ($value, 0) === $value) + $value = (float)$value; + return $value; + } + + return $value; + } + + /** + * Used in inlines to check for more inlines or quoted strings + * @access private + * @return array + */ + private function _inlineEscape($inline) { + // There's gotta be a cleaner way to do this... + // While pure sequences seem to be nesting just fine, + // pure mappings and mappings with sequences inside can't go very + // deep. This needs to be fixed. + + $seqs = array(); + $maps = array(); + $saved_strings = array(); + $saved_empties = array(); + + // Check for empty strings + $regex = '/("")|(\'\')/'; + if (preg_match_all($regex,$inline,$strings)) { + $saved_empties = $strings[0]; + $inline = preg_replace($regex,'YAMLEmpty',$inline); + } + unset($regex); + + // Check for strings + $regex = '/(?:(")|(?:\'))((?(1)[^"]+|[^\']+))(?(1)"|\')/'; + if (preg_match_all($regex,$inline,$strings)) { + $saved_strings = $strings[0]; + $inline = preg_replace($regex,'YAMLString',$inline); + } + unset($regex); + + // echo $inline; + + $i = 0; + do { + + // Check for sequences + while (preg_match('/\[([^{}\[\]]+)\]/U',$inline,$matchseqs)) { + $seqs[] = $matchseqs[0]; + $inline = preg_replace('/\[([^{}\[\]]+)\]/U', ('YAMLSeq' . (count($seqs) - 1) . 's'), $inline, 1); + } + + // Check for mappings + while (preg_match('/{([^\[\]{}]+)}/U',$inline,$matchmaps)) { + $maps[] = $matchmaps[0]; + $inline = preg_replace('/{([^\[\]{}]+)}/U', ('YAMLMap' . (count($maps) - 1) . 's'), $inline, 1); + } + + if ($i++ >= 10) break; + + } while (strpos ($inline, '[') !== false || strpos ($inline, '{') !== false); + + $explode = explode(',',$inline); + $explode = array_map('trim', $explode); + $stringi = 0; $i = 0; + + while (1) { + + // Re-add the sequences + if (!empty($seqs)) { + foreach ($explode as $key => $value) { + if (strpos($value,'YAMLSeq') !== false) { + foreach ($seqs as $seqk => $seq) { + $explode[$key] = str_replace(('YAMLSeq'.$seqk.'s'),$seq,$value); + $value = $explode[$key]; + } + } + } + } + + // Re-add the mappings + if (!empty($maps)) { + foreach ($explode as $key => $value) { + if (strpos($value,'YAMLMap') !== false) { + foreach ($maps as $mapk => $map) { + $explode[$key] = str_replace(('YAMLMap'.$mapk.'s'), $map, $value); + $value = $explode[$key]; + } + } + } + } + + + // Re-add the strings + if (!empty($saved_strings)) { + foreach ($explode as $key => $value) { + while (strpos($value,'YAMLString') !== false) { + $explode[$key] = preg_replace('/YAMLString/',$saved_strings[$stringi],$value, 1); + unset($saved_strings[$stringi]); + ++$stringi; + $value = $explode[$key]; + } + } + } + + + // Re-add the empties + if (!empty($saved_empties)) { + foreach ($explode as $key => $value) { + while (strpos($value,'YAMLEmpty') !== false) { + $explode[$key] = preg_replace('/YAMLEmpty/', '', $value, 1); + $value = $explode[$key]; + } + } + } + + $finished = true; + foreach ($explode as $key => $value) { + if (strpos($value,'YAMLSeq') !== false) { + $finished = false; break; + } + if (strpos($value,'YAMLMap') !== false) { + $finished = false; break; + } + if (strpos($value,'YAMLString') !== false) { + $finished = false; break; + } + if (strpos($value,'YAMLEmpty') !== false) { + $finished = false; break; + } + } + if ($finished) break; + + $i++; + if ($i > 10) + break; // Prevent infinite loops. + } + + + return $explode; + } + + private function literalBlockContinues ($line, $lineIndent) { + if (!trim($line)) return true; + if (strlen($line) - strlen(ltrim($line)) > $lineIndent) return true; + return false; + } + + private function referenceContentsByAlias ($alias) { + do { + if (!isset($this->SavedGroups[$alias])) { echo "Bad group name: $alias."; break; } + $groupPath = $this->SavedGroups[$alias]; + $value = $this->result; + foreach ($groupPath as $k) { + $value = $value[$k]; + } + } while (false); + return $value; + } + + private function addArrayInline ($array, $indent) { + $CommonGroupPath = $this->path; + if (empty ($array)) return false; + + foreach ($array as $k => $_) { + $this->addArray(array($k => $_), $indent); + $this->path = $CommonGroupPath; + } + return true; + } + + private function addArray ($incoming_data, $incoming_indent) { + + // print_r ($incoming_data); + + if (count ($incoming_data) > 1) + return $this->addArrayInline ($incoming_data, $incoming_indent); + + $key = key ($incoming_data); + $value = isset($incoming_data[$key]) ? $incoming_data[$key] : null; + if ($key === '__!YAMLZero') $key = '0'; + + if ($incoming_indent == 0 && !$this->_containsGroupAlias && !$this->_containsGroupAnchor) { // Shortcut for root-level values. + if ($key || $key === '' || $key === '0') { + $this->result[$key] = $value; + } else { + $this->result[] = $value; end ($this->result); $key = key ($this->result); + } + $this->path[$incoming_indent] = $key; + return; + } + + + + $history = array(); + // Unfolding inner array tree. + $history[] = $_arr = $this->result; + foreach ($this->path as $k) { + $history[] = $_arr = $_arr[$k]; + } + + if ($this->_containsGroupAlias) { + $value = $this->referenceContentsByAlias($this->_containsGroupAlias); + $this->_containsGroupAlias = false; + } + + + // Adding string or numeric key to the innermost level or $this->arr. + if (is_string($key) && $key == '<<') { + if (!is_array ($_arr)) { $_arr = array (); } + + $_arr = array_merge ($_arr, $value); + } else if ($key || $key === '' || $key === '0') { + if (!is_array ($_arr)) + $_arr = array ($key=>$value); + else + $_arr[$key] = $value; + } else { + if (!is_array ($_arr)) { $_arr = array ($value); $key = 0; } + else { $_arr[] = $value; end ($_arr); $key = key ($_arr); } + } + + $reverse_path = array_reverse($this->path); + $reverse_history = array_reverse ($history); + $reverse_history[0] = $_arr; + $cnt = count($reverse_history) - 1; + for ($i = 0; $i < $cnt; $i++) { + $reverse_history[$i+1][$reverse_path[$i]] = $reverse_history[$i]; + } + $this->result = $reverse_history[$cnt]; + + $this->path[$incoming_indent] = $key; + + if ($this->_containsGroupAnchor) { + $this->SavedGroups[$this->_containsGroupAnchor] = $this->path; + if (is_array ($value)) { + $k = key ($value); + if (!is_int ($k)) { + $this->SavedGroups[$this->_containsGroupAnchor][$incoming_indent + 2] = $k; + } + } + $this->_containsGroupAnchor = false; + } + + } + + private static function startsLiteralBlock ($line) { + $lastChar = substr (trim($line), -1); + if ($lastChar != '>' && $lastChar != '|') return false; + if ($lastChar == '|') return $lastChar; + // HTML tags should not be counted as literal blocks. + if (preg_match ('#<.*?>$#', $line)) return false; + return $lastChar; + } + + private static function greedilyNeedNextLine($line) { + $line = trim ($line); + if (!strlen($line)) return false; + if (substr ($line, -1, 1) == ']') return false; + if ($line[0] == '[') return true; + if (preg_match ('#^[^:]+?:\s*\[#', $line)) return true; + return false; + } + + private function addLiteralLine ($literalBlock, $line, $literalBlockStyle, $indent = -1) { + $line = self::stripIndent($line, $indent); + if ($literalBlockStyle !== '|') { + $line = self::stripIndent($line); + } + $line = rtrim ($line, "\r\n\t ") . "\n"; + if ($literalBlockStyle == '|') { + return $literalBlock . $line; + } + if (strlen($line) == 0) + return rtrim($literalBlock, ' ') . "\n"; + if ($line == "\n" && $literalBlockStyle == '>') { + return rtrim ($literalBlock, " \t") . "\n"; + } + if ($line != "\n") + $line = trim ($line, "\r\n ") . " "; + return $literalBlock . $line; + } + + function revertLiteralPlaceHolder ($lineArray, $literalBlock) { + foreach ($lineArray as $k => $_) { + if (is_array($_)) + $lineArray[$k] = $this->revertLiteralPlaceHolder ($_, $literalBlock); + else if (substr($_, -1 * strlen ($this->LiteralPlaceHolder)) == $this->LiteralPlaceHolder) + $lineArray[$k] = rtrim ($literalBlock, " \r\n"); + } + return $lineArray; + } + + private static function stripIndent ($line, $indent = -1) { + if ($indent == -1) $indent = strlen($line) - strlen(ltrim($line)); + return substr ($line, $indent); + } + + private function getParentPathByIndent ($indent) { + if ($indent == 0) return array(); + $linePath = $this->path; + do { + end($linePath); $lastIndentInParentPath = key($linePath); + if ($indent <= $lastIndentInParentPath) array_pop ($linePath); + } while ($indent <= $lastIndentInParentPath); + return $linePath; + } + + + private function clearBiggerPathValues ($indent) { + + + if ($indent == 0) $this->path = array(); + if (empty ($this->path)) return true; + + foreach ($this->path as $k => $_) { + if ($k > $indent) unset ($this->path[$k]); + } + + return true; + } + + + private static function isComment ($line) { + if (!$line) return false; + if ($line[0] == '#') return true; + if (trim($line, " \r\n\t") == '---') return true; + return false; + } + + private static function isEmpty ($line) { + return (trim ($line) === ''); + } + + + private function isArrayElement ($line) { + if (!$line || !is_scalar($line)) return false; + if (substr($line, 0, 2) != '- ') return false; + if (strlen ($line) > 3) + if (substr($line,0,3) == '---') return false; + + return true; + } + + private function isHashElement ($line) { + return strpos($line, ':'); + } + + private function isLiteral ($line) { + if ($this->isArrayElement($line)) return false; + if ($this->isHashElement($line)) return false; + return true; + } + + + private static function unquote ($value) { + if (!$value) return $value; + if (!is_string($value)) return $value; + if ($value[0] == '\'') return trim ($value, '\''); + if ($value[0] == '"') return trim ($value, '"'); + return $value; + } + + private function startsMappedSequence ($line) { + return (substr($line, 0, 2) == '- ' && substr ($line, -1, 1) == ':'); + } + + private function returnMappedSequence ($line) { + $array = array(); + $key = self::unquote(trim(substr($line,1,-1))); + $array[$key] = array(); + $this->delayedPath = array(strpos ($line, $key) + $this->indent => $key); + return array($array); + } + + private function checkKeysInValue($value) { + if (strchr('[{"\'', $value[0]) === false) { + if (strchr($value, ': ') !== false) { + throw new Exception('Too many keys: '.$value); + } + } + } + + private function returnMappedValue ($line) { + $this->checkKeysInValue($line); + $array = array(); + $key = self::unquote (trim(substr($line,0,-1))); + $array[$key] = ''; + return $array; + } + + private function startsMappedValue ($line) { + return (substr ($line, -1, 1) == ':'); + } + + private function isPlainArray ($line) { + return ($line[0] == '[' && substr ($line, -1, 1) == ']'); + } + + private function returnPlainArray ($line) { + return $this->_toType($line); + } + + private function returnKeyValuePair ($line) { + $array = array(); + $key = ''; + if (strpos ($line, ': ')) { + // It's a key/value pair most likely + // If the key is in double quotes pull it out + if (($line[0] == '"' || $line[0] == "'") && preg_match('/^(["\'](.*)["\'](\s)*:)/',$line,$matches)) { + $value = trim(str_replace($matches[1],'',$line)); + $key = $matches[2]; + } else { + // Do some guesswork as to the key and the value + $explode = explode(': ', $line); + $key = trim(array_shift($explode)); + $value = trim(implode(': ', $explode)); + $this->checkKeysInValue($value); + } + // Set the type of the value. Int, string, etc + $value = $this->_toType($value); + + if ($key === '0') $key = '__!YAMLZero'; + $array[$key] = $value; + } else { + $array = array ($line); + } + return $array; + + } + + + private function returnArrayElement ($line) { + if (strlen($line) <= 1) return array(array()); // Weird %) + $array = array(); + $value = trim(substr($line,1)); + $value = $this->_toType($value); + if ($this->isArrayElement($value)) { + $value = $this->returnArrayElement($value); + } + $array[] = $value; + return $array; + } + + + private function nodeContainsGroup ($line) { + $symbolsForReference = 'A-z0-9_\-'; + if (strpos($line, '&') === false && strpos($line, '*') === false) return false; // Please die fast ;-) + if ($line[0] == '&' && preg_match('/^(&['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1]; + if ($line[0] == '*' && preg_match('/^(\*['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1]; + if (preg_match('/(&['.$symbolsForReference.']+)$/', $line, $matches)) return $matches[1]; + if (preg_match('/(\*['.$symbolsForReference.']+$)/', $line, $matches)) return $matches[1]; + if (preg_match ('#^\s*<<\s*:\s*(\*[^\s]+).*$#', $line, $matches)) return $matches[1]; + return false; + + } + + private function addGroup ($line, $group) { + if ($group[0] == '&') $this->_containsGroupAnchor = substr ($group, 1); + if ($group[0] == '*') $this->_containsGroupAlias = substr ($group, 1); + //print_r ($this->path); + } + + private function stripGroup ($line, $group) { + $line = trim(str_replace($group, '', $line)); + return $line; + } +} +} + +// Enable use of Spyc from command line +// The syntax is the following: php Spyc.php spyc.yaml + +do { + if (PHP_SAPI != 'cli') break; + if (empty ($_SERVER['argc']) || $_SERVER['argc'] < 2) break; + if (empty ($_SERVER['PHP_SELF']) || FALSE === strpos ($_SERVER['PHP_SELF'], 'Spyc.php') ) break; + $file = $argv[1]; + echo json_encode (spyc_load_file ($file)); +} while (0); diff --git a/plugins/vdomah/blogviews/vendor/mustangostang/spyc/composer.json b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/composer.json new file mode 100644 index 000000000..e5ab77684 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/composer.json @@ -0,0 +1,30 @@ +{ + "name": "mustangostang/spyc", + "description": "A simple YAML loader/dumper class for PHP", + "type": "library", + "keywords": [ + "spyc", + "yaml", + "yml" + ], + "homepage": "https://github.com/mustangostang/spyc/", + "authors" : [{ + "name": "mustangostang", + "email": "vlad.andersen@gmail.com" + }], + "license": "MIT", + "require": { + "php": ">=5.3.1" + }, + "autoload": { + "files": [ "Spyc.php" ] + }, + "require-dev": { + "phpunit/phpunit": "4.3.*@dev" + }, + "extra": { + "branch-alias": { + "dev-master": "0.5.x-dev" + } + } +} diff --git a/plugins/vdomah/blogviews/vendor/mustangostang/spyc/examples/yaml-dump.php b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/examples/yaml-dump.php new file mode 100644 index 000000000..9d2160aaf --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/examples/yaml-dump.php @@ -0,0 +1,25 @@ + 'A sequence','second' => 'of mapped values'); +$array['Mapped'] = array('A sequence','which is mapped'); +$array['A Note'] = 'What if your text is too long?'; +$array['Another Note'] = 'If that is the case, the dumper will probably fold your text by using a block. Kinda like this.'; +$array['The trick?'] = 'The trick is that we overrode the default indent, 2, to 4 and the default wordwrap, 40, to 60.'; +$array['Old Dog'] = "And if you want\n to preserve line breaks, \ngo ahead!"; +$array['key:withcolon'] = "Should support this to"; + +$yaml = Spyc::YAMLDump($array,4,60); diff --git a/plugins/vdomah/blogviews/vendor/mustangostang/spyc/examples/yaml-load.php b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/examples/yaml-load.php new file mode 100644 index 000000000..9e457e1e1 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/examples/yaml-load.php @@ -0,0 +1,21 @@ +spyc.yaml loaded into PHP:
'; +print_r($array); +echo ''; + + +echo '
YAML Data dumped back:
'; +echo Spyc::YAMLDump($array); +echo '
'; diff --git a/plugins/vdomah/blogviews/vendor/mustangostang/spyc/php4/5to4.php b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/php4/5to4.php new file mode 100644 index 000000000..5a48694f0 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/php4/5to4.php @@ -0,0 +1,17 @@ +', $code); + $f = fopen ($dest, 'w'); + fwrite($f, $code); + fclose ($f); + print "Written to $dest.\n"; +} \ No newline at end of file diff --git a/plugins/vdomah/blogviews/vendor/mustangostang/spyc/php4/spyc.php4 b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/php4/spyc.php4 new file mode 100644 index 000000000..73f08cc07 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/php4/spyc.php4 @@ -0,0 +1,1023 @@ + + * @author Chris Wanstrath + * @link http://code.google.com/p/spyc/ + * @copyright Copyright 2005-2006 Chris Wanstrath, 2006-2009 Vlad Andersen + * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @package Spyc + */ + +if (!function_exists('spyc_load')) { + /** + * Parses YAML to array. + * @param string $string YAML string. + * @return array + */ + function spyc_load ($string) { + return Spyc::YAMLLoadString($string); + } +} + +if (!function_exists('spyc_load_file')) { + /** + * Parses YAML to array. + * @param string $file Path to YAML file. + * @return array + */ + function spyc_load_file ($file) { + return Spyc::YAMLLoad($file); + } +} + +/** + * The Simple PHP YAML Class. + * + * This class can be used to read a YAML file and convert its contents + * into a PHP array. It currently supports a very limited subsection of + * the YAML spec. + * + * Usage: + * + * $Spyc = new Spyc; + * $array = $Spyc->load($file); + * + * or: + * + * $array = Spyc::YAMLLoad($file); + * + * or: + * + * $array = spyc_load_file($file); + * + * @package Spyc + */ +class Spyc { + + // SETTINGS + + /** + * Setting this to true will force YAMLDump to enclose any string value in + * quotes. False by default. + * + * @var bool + */ + var $setting_dump_force_quotes = false; + + /** + * Setting this to true will forse YAMLLoad to use syck_load function when + * possible. False by default. + * @var bool + */ + var $setting_use_syck_is_possible = false; + + + + /**#@+ + * @access private + * @var mixed + */ + var $_dumpIndent; + var $_dumpWordWrap; + var $_containsGroupAnchor = false; + var $_containsGroupAlias = false; + var $path; + var $result; + var $LiteralPlaceHolder = '___YAML_Literal_Block___'; + var $SavedGroups = array(); + var $indent; + /** + * Path modifier that should be applied after adding current element. + * @var array + */ + var $delayedPath = array(); + + /**#@+ + * @access public + * @var mixed + */ + var $_nodeId; + +/** + * Load a valid YAML string to Spyc. + * @param string $input + * @return array + */ + function load ($input) { + return $this->__loadString($input); + } + + /** + * Load a valid YAML file to Spyc. + * @param string $file + * @return array + */ + function loadFile ($file) { + return $this->__load($file); + } + + /** + * Load YAML into a PHP array statically + * + * The load method, when supplied with a YAML stream (string or file), + * will do its best to convert YAML in a file into a PHP array. Pretty + * simple. + * Usage: + * + * $array = Spyc::YAMLLoad('lucky.yaml'); + * print_r($array); + * + * @access public + * @return array + * @param string $input Path of YAML file or string containing YAML + */ + function YAMLLoad($input) { + $Spyc = new Spyc; + return $Spyc->__load($input); + } + + /** + * Load a string of YAML into a PHP array statically + * + * The load method, when supplied with a YAML string, will do its best + * to convert YAML in a string into a PHP array. Pretty simple. + * + * Note: use this function if you don't want files from the file system + * loaded and processed as YAML. This is of interest to people concerned + * about security whose input is from a string. + * + * Usage: + * + * $array = Spyc::YAMLLoadString("---\n0: hello world\n"); + * print_r($array); + * + * @access public + * @return array + * @param string $input String containing YAML + */ + function YAMLLoadString($input) { + $Spyc = new Spyc; + return $Spyc->__loadString($input); + } + + /** + * Dump YAML from PHP array statically + * + * The dump method, when supplied with an array, will do its best + * to convert the array into friendly YAML. Pretty simple. Feel free to + * save the returned string as nothing.yaml and pass it around. + * + * Oh, and you can decide how big the indent is and what the wordwrap + * for folding is. Pretty cool -- just pass in 'false' for either if + * you want to use the default. + * + * Indent's default is 2 spaces, wordwrap's default is 40 characters. And + * you can turn off wordwrap by passing in 0. + * + * @access public + * @return string + * @param array $array PHP array + * @param int $indent Pass in false to use the default, which is 2 + * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40) + */ + function YAMLDump($array,$indent = false,$wordwrap = false) { + $spyc = new Spyc; + return $spyc->dump($array,$indent,$wordwrap); + } + + + /** + * Dump PHP array to YAML + * + * The dump method, when supplied with an array, will do its best + * to convert the array into friendly YAML. Pretty simple. Feel free to + * save the returned string as tasteful.yaml and pass it around. + * + * Oh, and you can decide how big the indent is and what the wordwrap + * for folding is. Pretty cool -- just pass in 'false' for either if + * you want to use the default. + * + * Indent's default is 2 spaces, wordwrap's default is 40 characters. And + * you can turn off wordwrap by passing in 0. + * + * @access public + * @return string + * @param array $array PHP array + * @param int $indent Pass in false to use the default, which is 2 + * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40) + */ + function dump($array,$indent = false,$wordwrap = false) { + // Dumps to some very clean YAML. We'll have to add some more features + // and options soon. And better support for folding. + + // New features and options. + if ($indent === false or !is_numeric($indent)) { + $this->_dumpIndent = 2; + } else { + $this->_dumpIndent = $indent; + } + + if ($wordwrap === false or !is_numeric($wordwrap)) { + $this->_dumpWordWrap = 40; + } else { + $this->_dumpWordWrap = $wordwrap; + } + + // New YAML document + $string = "---\n"; + + // Start at the base of the array and move through it. + if ($array) { + $array = (array)$array; + $first_key = key($array); + + $previous_key = -1; + foreach ($array as $key => $value) { + $string .= $this->_yamlize($key,$value,0,$previous_key, $first_key); + $previous_key = $key; + } + } + return $string; + } + + /** + * Attempts to convert a key / value array item to YAML + * @access private + * @return string + * @param $key The name of the key + * @param $value The value of the item + * @param $indent The indent of the current node + */ + function _yamlize($key,$value,$indent, $previous_key = -1, $first_key = 0) { + if (is_array($value)) { + if (empty ($value)) + return $this->_dumpNode($key, array(), $indent, $previous_key, $first_key); + // It has children. What to do? + // Make it the right kind of item + $string = $this->_dumpNode($key, NULL, $indent, $previous_key, $first_key); + // Add the indent + $indent += $this->_dumpIndent; + // Yamlize the array + $string .= $this->_yamlizeArray($value,$indent); + } elseif (!is_array($value)) { + // It doesn't have children. Yip. + $string = $this->_dumpNode($key, $value, $indent, $previous_key, $first_key); + } + return $string; + } + + /** + * Attempts to convert an array to YAML + * @access private + * @return string + * @param $array The array you want to convert + * @param $indent The indent of the current level + */ + function _yamlizeArray($array,$indent) { + if (is_array($array)) { + $string = ''; + $previous_key = -1; + $first_key = key($array); + foreach ($array as $key => $value) { + $string .= $this->_yamlize($key, $value, $indent, $previous_key, $first_key); + $previous_key = $key; + } + return $string; + } else { + return false; + } + } + + /** + * Returns YAML from a key and a value + * @access private + * @return string + * @param $key The name of the key + * @param $value The value of the item + * @param $indent The indent of the current node + */ + function _dumpNode($key, $value, $indent, $previous_key = -1, $first_key = 0) { + // do some folding here, for blocks + if (is_string ($value) && ((strpos($value,"\n") !== false || strpos($value,": ") !== false || strpos($value,"- ") !== false || + strpos($value,"*") !== false || strpos($value,"#") !== false || strpos($value,"<") !== false || strpos($value,">") !== false || + strpos($value,"[") !== false || strpos($value,"]") !== false || strpos($value,"{") !== false || strpos($value,"}") !== false) || substr ($value, -1, 1) == ':')) { + $value = $this->_doLiteralBlock($value,$indent); + } else { + $value = $this->_doFolding($value,$indent); + if (is_bool($value)) { + $value = ($value) ? "true" : "false"; + } + } + + if ($value === array()) $value = '[ ]'; + + $spaces = str_repeat(' ',$indent); + + if (is_int($key) && $key - 1 == $previous_key && $first_key===0) { + // It's a sequence + $string = $spaces.'- '.$value."\n"; + } else { + if ($first_key===0) throw new Exception('Keys are all screwy. The first one was zero, now it\'s "'. $key .'"'); + // It's mapped + if (strpos($key, ":") !== false) { $key = '"' . $key . '"'; } + $string = $spaces.$key.': '.$value."\n"; + } + return $string; + } + + /** + * Creates a literal block for dumping + * @access private + * @return string + * @param $value + * @param $indent int The value of the indent + */ + function _doLiteralBlock($value,$indent) { + if (strpos($value, "\n") === false && strpos($value, "'") === false) { + return sprintf ("'%s'", $value); + } + if (strpos($value, "\n") === false && strpos($value, '"') === false) { + return sprintf ('"%s"', $value); + } + $exploded = explode("\n",$value); + $newValue = '|'; + $indent += $this->_dumpIndent; + $spaces = str_repeat(' ',$indent); + foreach ($exploded as $line) { + $newValue .= "\n" . $spaces . trim($line); + } + return $newValue; + } + + /** + * Folds a string of text, if necessary + * @access private + * @return string + * @param $value The string you wish to fold + */ + function _doFolding($value,$indent) { + // Don't do anything if wordwrap is set to 0 + + if ($this->_dumpWordWrap !== 0 && is_string ($value) && strlen($value) > $this->_dumpWordWrap) { + $indent += $this->_dumpIndent; + $indent = str_repeat(' ',$indent); + $wrapped = wordwrap($value,$this->_dumpWordWrap,"\n$indent"); + $value = ">\n".$indent.$wrapped; + } else { + if ($this->setting_dump_force_quotes && is_string ($value)) + $value = '"' . $value . '"'; + } + + + return $value; + } + +// LOADING FUNCTIONS + + function __load($input) { + $Source = $this->loadFromSource($input); + return $this->loadWithSource($Source); + } + + function __loadString($input) { + $Source = $this->loadFromString($input); + return $this->loadWithSource($Source); + } + + function loadWithSource($Source) { + if (empty ($Source)) return array(); + if ($this->setting_use_syck_is_possible && function_exists ('syck_load')) { + $array = syck_load (implode ('', $Source)); + return is_array($array) ? $array : array(); + } + + $this->path = array(); + $this->result = array(); + + $cnt = count($Source); + for ($i = 0; $i < $cnt; $i++) { + $line = $Source[$i]; + + $this->indent = strlen($line) - strlen(ltrim($line)); + $tempPath = $this->getParentPathByIndent($this->indent); + $line = $this->stripIndent($line, $this->indent); + if ($this->isComment($line)) continue; + if ($this->isEmpty($line)) continue; + $this->path = $tempPath; + + $literalBlockStyle = $this->startsLiteralBlock($line); + if ($literalBlockStyle) { + $line = rtrim ($line, $literalBlockStyle . " \n"); + $literalBlock = ''; + $line .= $this->LiteralPlaceHolder; + + while (++$i < $cnt && $this->literalBlockContinues($Source[$i], $this->indent)) { + $literalBlock = $this->addLiteralLine($literalBlock, $Source[$i], $literalBlockStyle); + } + $i--; + } + + while (++$i < $cnt && $this->greedilyNeedNextLine($line)) { + $line = rtrim ($line, " \n\t\r") . ' ' . ltrim ($Source[$i], " \t"); + } + $i--; + + + + if (strpos ($line, '#')) { + if (strpos ($line, '"') === false && strpos ($line, "'") === false) + $line = preg_replace('/\s+#(.+)$/','',$line); + } + + $lineArray = $this->_parseLine($line); + + if ($literalBlockStyle) + $lineArray = $this->revertLiteralPlaceHolder ($lineArray, $literalBlock); + + $this->addArray($lineArray, $this->indent); + + foreach ($this->delayedPath as $indent => $delayedPath) + $this->path[$indent] = $delayedPath; + + $this->delayedPath = array(); + + } + return $this->result; + } + + function loadFromSource ($input) { + if (!empty($input) && strpos($input, "\n") === false && file_exists($input)) + return file($input); + + return $this->loadFromString($input); + } + + function loadFromString ($input) { + $lines = explode("\n",$input); + foreach ($lines as $k => $_) { + $lines[$k] = rtrim ($_, "\r"); + } + return $lines; + } + + /** + * Parses YAML code and returns an array for a node + * @access private + * @return array + * @param string $line A line from the YAML file + */ + function _parseLine($line) { + if (!$line) return array(); + $line = trim($line); + + if (!$line) return array(); + $array = array(); + + $group = $this->nodeContainsGroup($line); + if ($group) { + $this->addGroup($line, $group); + $line = $this->stripGroup ($line, $group); + } + + if ($this->startsMappedSequence($line)) + return $this->returnMappedSequence($line); + + if ($this->startsMappedValue($line)) + return $this->returnMappedValue($line); + + if ($this->isArrayElement($line)) + return $this->returnArrayElement($line); + + if ($this->isPlainArray($line)) + return $this->returnPlainArray($line); + + + return $this->returnKeyValuePair($line); + + } + + /** + * Finds the type of the passed value, returns the value as the new type. + * @access private + * @param string $value + * @return mixed + */ + function _toType($value) { + if ($value === '') return null; + $first_character = $value[0]; + $last_character = substr($value, -1, 1); + + $is_quoted = false; + do { + if (!$value) break; + if ($first_character != '"' && $first_character != "'") break; + if ($last_character != '"' && $last_character != "'") break; + $is_quoted = true; + } while (0); + + if ($is_quoted) + return strtr(substr ($value, 1, -1), array ('\\"' => '"', '\'\'' => '\'', '\\\'' => '\'')); + + if (strpos($value, ' #') !== false) + $value = preg_replace('/\s+#(.+)$/','',$value); + + if ($first_character == '[' && $last_character == ']') { + // Take out strings sequences and mappings + $innerValue = trim(substr ($value, 1, -1)); + if ($innerValue === '') return array(); + $explode = $this->_inlineEscape($innerValue); + // Propagate value array + $value = array(); + foreach ($explode as $v) { + $value[] = $this->_toType($v); + } + return $value; + } + + if (strpos($value,': ')!==false && $first_character != '{') { + $array = explode(': ',$value); + $key = trim($array[0]); + array_shift($array); + $value = trim(implode(': ',$array)); + $value = $this->_toType($value); + return array($key => $value); + } + + if ($first_character == '{' && $last_character == '}') { + $innerValue = trim(substr ($value, 1, -1)); + if ($innerValue === '') return array(); + // Inline Mapping + // Take out strings sequences and mappings + $explode = $this->_inlineEscape($innerValue); + // Propagate value array + $array = array(); + foreach ($explode as $v) { + $SubArr = $this->_toType($v); + if (empty($SubArr)) continue; + if (is_array ($SubArr)) { + $array[key($SubArr)] = $SubArr[key($SubArr)]; continue; + } + $array[] = $SubArr; + } + return $array; + } + + if ($value == 'null' || $value == 'NULL' || $value == 'Null' || $value == '' || $value == '~') { + return null; + } + + if (intval($first_character) > 0 && preg_match ('/^[1-9]+[0-9]*$/', $value)) { + $intvalue = (int)$value; + if ($intvalue != PHP_INT_MAX) + $value = $intvalue; + return $value; + } + + if (in_array($value, + array('true', 'on', '+', 'yes', 'y', 'True', 'TRUE', 'On', 'ON', 'YES', 'Yes', 'Y'))) { + return true; + } + + if (in_array(strtolower($value), + array('false', 'off', '-', 'no', 'n'))) { + return false; + } + + if (is_numeric($value)) { + if ($value === '0') return 0; + if (trim ($value, 0) === $value) + $value = (float)$value; + return $value; + } + + return $value; + } + + /** + * Used in inlines to check for more inlines or quoted strings + * @access private + * @return array + */ + function _inlineEscape($inline) { + // There's gotta be a cleaner way to do this... + // While pure sequences seem to be nesting just fine, + // pure mappings and mappings with sequences inside can't go very + // deep. This needs to be fixed. + + $seqs = array(); + $maps = array(); + $saved_strings = array(); + + // Check for strings + $regex = '/(?:(")|(?:\'))((?(1)[^"]+|[^\']+))(?(1)"|\')/'; + if (preg_match_all($regex,$inline,$strings)) { + $saved_strings = $strings[0]; + $inline = preg_replace($regex,'YAMLString',$inline); + } + unset($regex); + + $i = 0; + do { + + // Check for sequences + while (preg_match('/\[([^{}\[\]]+)\]/U',$inline,$matchseqs)) { + $seqs[] = $matchseqs[0]; + $inline = preg_replace('/\[([^{}\[\]]+)\]/U', ('YAMLSeq' . (count($seqs) - 1) . 's'), $inline, 1); + } + + // Check for mappings + while (preg_match('/{([^\[\]{}]+)}/U',$inline,$matchmaps)) { + $maps[] = $matchmaps[0]; + $inline = preg_replace('/{([^\[\]{}]+)}/U', ('YAMLMap' . (count($maps) - 1) . 's'), $inline, 1); + } + + if ($i++ >= 10) break; + + } while (strpos ($inline, '[') !== false || strpos ($inline, '{') !== false); + + $explode = explode(', ',$inline); + $stringi = 0; $i = 0; + + while (1) { + + // Re-add the sequences + if (!empty($seqs)) { + foreach ($explode as $key => $value) { + if (strpos($value,'YAMLSeq') !== false) { + foreach ($seqs as $seqk => $seq) { + $explode[$key] = str_replace(('YAMLSeq'.$seqk.'s'),$seq,$value); + $value = $explode[$key]; + } + } + } + } + + // Re-add the mappings + if (!empty($maps)) { + foreach ($explode as $key => $value) { + if (strpos($value,'YAMLMap') !== false) { + foreach ($maps as $mapk => $map) { + $explode[$key] = str_replace(('YAMLMap'.$mapk.'s'), $map, $value); + $value = $explode[$key]; + } + } + } + } + + + // Re-add the strings + if (!empty($saved_strings)) { + foreach ($explode as $key => $value) { + while (strpos($value,'YAMLString') !== false) { + $explode[$key] = preg_replace('/YAMLString/',$saved_strings[$stringi],$value, 1); + unset($saved_strings[$stringi]); + ++$stringi; + $value = $explode[$key]; + } + } + } + + $finished = true; + foreach ($explode as $key => $value) { + if (strpos($value,'YAMLSeq') !== false) { + $finished = false; break; + } + if (strpos($value,'YAMLMap') !== false) { + $finished = false; break; + } + if (strpos($value,'YAMLString') !== false) { + $finished = false; break; + } + } + if ($finished) break; + + $i++; + if ($i > 10) + break; // Prevent infinite loops. + } + + return $explode; + } + + function literalBlockContinues ($line, $lineIndent) { + if (!trim($line)) return true; + if (strlen($line) - strlen(ltrim($line)) > $lineIndent) return true; + return false; + } + + function referenceContentsByAlias ($alias) { + do { + if (!isset($this->SavedGroups[$alias])) { echo "Bad group name: $alias."; break; } + $groupPath = $this->SavedGroups[$alias]; + $value = $this->result; + foreach ($groupPath as $k) { + $value = $value[$k]; + } + } while (false); + return $value; + } + + function addArrayInline ($array, $indent) { + $CommonGroupPath = $this->path; + if (empty ($array)) return false; + + foreach ($array as $k => $_) { + $this->addArray(array($k => $_), $indent); + $this->path = $CommonGroupPath; + } + return true; + } + + function addArray ($incoming_data, $incoming_indent) { + + // print_r ($incoming_data); + + if (count ($incoming_data) > 1) + return $this->addArrayInline ($incoming_data, $incoming_indent); + + $key = key ($incoming_data); + $value = isset($incoming_data[$key]) ? $incoming_data[$key] : null; + if ($key === '__!YAMLZero') $key = '0'; + + if ($incoming_indent == 0 && !$this->_containsGroupAlias && !$this->_containsGroupAnchor) { // Shortcut for root-level values. + if ($key || $key === '' || $key === '0') { + $this->result[$key] = $value; + } else { + $this->result[] = $value; end ($this->result); $key = key ($this->result); + } + $this->path[$incoming_indent] = $key; + return; + } + + + + $history = array(); + // Unfolding inner array tree. + $history[] = $_arr = $this->result; + foreach ($this->path as $k) { + $history[] = $_arr = $_arr[$k]; + } + + if ($this->_containsGroupAlias) { + $value = $this->referenceContentsByAlias($this->_containsGroupAlias); + $this->_containsGroupAlias = false; + } + + + // Adding string or numeric key to the innermost level or $this->arr. + if (is_string($key) && $key == '<<') { + if (!is_array ($_arr)) { $_arr = array (); } + $_arr = array_merge ($_arr, $value); + } else if ($key || $key === '' || $key === '0') { + $_arr[$key] = $value; + } else { + if (!is_array ($_arr)) { $_arr = array ($value); $key = 0; } + else { $_arr[] = $value; end ($_arr); $key = key ($_arr); } + } + + $reverse_path = array_reverse($this->path); + $reverse_history = array_reverse ($history); + $reverse_history[0] = $_arr; + $cnt = count($reverse_history) - 1; + for ($i = 0; $i < $cnt; $i++) { + $reverse_history[$i+1][$reverse_path[$i]] = $reverse_history[$i]; + } + $this->result = $reverse_history[$cnt]; + + $this->path[$incoming_indent] = $key; + + if ($this->_containsGroupAnchor) { + $this->SavedGroups[$this->_containsGroupAnchor] = $this->path; + if (is_array ($value)) { + $k = key ($value); + if (!is_int ($k)) { + $this->SavedGroups[$this->_containsGroupAnchor][$incoming_indent + 2] = $k; + } + } + $this->_containsGroupAnchor = false; + } + + } + + function startsLiteralBlock ($line) { + $lastChar = substr (trim($line), -1); + if ($lastChar != '>' && $lastChar != '|') return false; + if ($lastChar == '|') return $lastChar; + // HTML tags should not be counted as literal blocks. + if (preg_match ('#<.*?>$#', $line)) return false; + return $lastChar; + } + + function greedilyNeedNextLine($line) { + $line = trim ($line); + if (!strlen($line)) return false; + if (substr ($line, -1, 1) == ']') return false; + if ($line[0] == '[') return true; + if (preg_match ('#^[^:]+?:\s*\[#', $line)) return true; + return false; + } + + function addLiteralLine ($literalBlock, $line, $literalBlockStyle) { + $line = $this->stripIndent($line); + $line = rtrim ($line, "\r\n\t ") . "\n"; + if ($literalBlockStyle == '|') { + return $literalBlock . $line; + } + if (strlen($line) == 0) + return rtrim($literalBlock, ' ') . "\n"; + if ($line == "\n" && $literalBlockStyle == '>') { + return rtrim ($literalBlock, " \t") . "\n"; + } + if ($line != "\n") + $line = trim ($line, "\r\n ") . " "; + return $literalBlock . $line; + } + + function revertLiteralPlaceHolder ($lineArray, $literalBlock) { + foreach ($lineArray as $k => $_) { + if (is_array($_)) + $lineArray[$k] = $this->revertLiteralPlaceHolder ($_, $literalBlock); + else if (substr($_, -1 * strlen ($this->LiteralPlaceHolder)) == $this->LiteralPlaceHolder) + $lineArray[$k] = rtrim ($literalBlock, " \r\n"); + } + return $lineArray; + } + + function stripIndent ($line, $indent = -1) { + if ($indent == -1) $indent = strlen($line) - strlen(ltrim($line)); + return substr ($line, $indent); + } + + function getParentPathByIndent ($indent) { + if ($indent == 0) return array(); + $linePath = $this->path; + do { + end($linePath); $lastIndentInParentPath = key($linePath); + if ($indent <= $lastIndentInParentPath) array_pop ($linePath); + } while ($indent <= $lastIndentInParentPath); + return $linePath; + } + + + function clearBiggerPathValues ($indent) { + + + if ($indent == 0) $this->path = array(); + if (empty ($this->path)) return true; + + foreach ($this->path as $k => $_) { + if ($k > $indent) unset ($this->path[$k]); + } + + return true; + } + + + function isComment ($line) { + if (!$line) return false; + if ($line[0] == '#') return true; + if (trim($line, " \r\n\t") == '---') return true; + return false; + } + + function isEmpty ($line) { + return (trim ($line) === ''); + } + + + function isArrayElement ($line) { + if (!$line) return false; + if ($line[0] != '-') return false; + if (strlen ($line) > 3) + if (substr($line,0,3) == '---') return false; + + return true; + } + + function isHashElement ($line) { + return strpos($line, ':'); + } + + function isLiteral ($line) { + if ($this->isArrayElement($line)) return false; + if ($this->isHashElement($line)) return false; + return true; + } + + + function unquote ($value) { + if (!$value) return $value; + if (!is_string($value)) return $value; + if ($value[0] == '\'') return trim ($value, '\''); + if ($value[0] == '"') return trim ($value, '"'); + return $value; + } + + function startsMappedSequence ($line) { + return ($line[0] == '-' && substr ($line, -1, 1) == ':'); + } + + function returnMappedSequence ($line) { + $array = array(); + $key = $this->unquote(trim(substr($line,1,-1))); + $array[$key] = array(); + $this->delayedPath = array(strpos ($line, $key) + $this->indent => $key); + return array($array); + } + + function returnMappedValue ($line) { + $array = array(); + $key = $this->unquote (trim(substr($line,0,-1))); + $array[$key] = ''; + return $array; + } + + function startsMappedValue ($line) { + return (substr ($line, -1, 1) == ':'); + } + + function isPlainArray ($line) { + return ($line[0] == '[' && substr ($line, -1, 1) == ']'); + } + + function returnPlainArray ($line) { + return $this->_toType($line); + } + + function returnKeyValuePair ($line) { + $array = array(); + $key = ''; + if (strpos ($line, ':')) { + // It's a key/value pair most likely + // If the key is in double quotes pull it out + if (($line[0] == '"' || $line[0] == "'") && preg_match('/^(["\'](.*)["\'](\s)*:)/',$line,$matches)) { + $value = trim(str_replace($matches[1],'',$line)); + $key = $matches[2]; + } else { + // Do some guesswork as to the key and the value + $explode = explode(':',$line); + $key = trim($explode[0]); + array_shift($explode); + $value = trim(implode(':',$explode)); + } + // Set the type of the value. Int, string, etc + $value = $this->_toType($value); + if ($key === '0') $key = '__!YAMLZero'; + $array[$key] = $value; + } else { + $array = array ($line); + } + return $array; + + } + + + function returnArrayElement ($line) { + if (strlen($line) <= 1) return array(array()); // Weird %) + $array = array(); + $value = trim(substr($line,1)); + $value = $this->_toType($value); + $array[] = $value; + return $array; + } + + + function nodeContainsGroup ($line) { + $symbolsForReference = 'A-z0-9_\-'; + if (strpos($line, '&') === false && strpos($line, '*') === false) return false; // Please die fast ;-) + if ($line[0] == '&' && preg_match('/^(&['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1]; + if ($line[0] == '*' && preg_match('/^(\*['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1]; + if (preg_match('/(&['.$symbolsForReference.']+)$/', $line, $matches)) return $matches[1]; + if (preg_match('/(\*['.$symbolsForReference.']+$)/', $line, $matches)) return $matches[1]; + if (preg_match ('#^\s*<<\s*:\s*(\*[^\s]+).*$#', $line, $matches)) return $matches[1]; + return false; + + } + + function addGroup ($line, $group) { + if ($group[0] == '&') $this->_containsGroupAnchor = substr ($group, 1); + if ($group[0] == '*') $this->_containsGroupAlias = substr ($group, 1); + //print_r ($this->path); + } + + function stripGroup ($line, $group) { + $line = trim(str_replace($group, '', $line)); + return $line; + } +} + +// Enable use of Spyc from command line +// The syntax is the following: php spyc.php spyc.yaml + +define ('SPYC_FROM_COMMAND_LINE', false); + +do { + if (!SPYC_FROM_COMMAND_LINE) break; + if (empty ($_SERVER['argc']) || $_SERVER['argc'] < 2) break; + if (empty ($_SERVER['PHP_SELF']) || $_SERVER['PHP_SELF'] != 'spyc.php') break; + $file = $argv[1]; + printf ("Spyc loading file: %s\n", $file); + print_r (spyc_load_file ($file)); +} while (0); \ No newline at end of file diff --git a/plugins/vdomah/blogviews/vendor/mustangostang/spyc/php4/test.php4 b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/php4/test.php4 new file mode 100644 index 000000000..315f5019d --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/php4/test.php4 @@ -0,0 +1,162 @@ + "1.5ghz", "ram" => "1 gig", + "os" => "os x 10.4.1")) + die('Sequence 4 failed'); + +# Mapped sequence +if ($yaml['domains'] != array("yaml.org", "php.net")) + die("Key: 'domains' failed"); + +# A sequence like this. +if ($yaml[5] != array("program" => "Adium", "platform" => "OS X", + "type" => "Chat Client")) + die('Sequence 5 failed'); + +# A folded block as a mapped value +if ($yaml['no time'] != "There isn't any time for your tricks!\nDo you understand?") + die("Key: 'no time' failed"); + +# A literal block as a mapped value +if ($yaml['some time'] != "There is nothing but time\nfor your tricks.") + die("Key: 'some time' failed"); + +# Crazy combinations +if ($yaml['databases'] != array( array("name" => "spartan", "notes" => + array( "Needs to be backed up", + "Needs to be normalized" ), + "type" => "mysql" ))) + die("Key: 'databases' failed"); + +# You can be a bit tricky +if ($yaml["if: you'd"] != "like") + die("Key: 'if: you\'d' failed"); + +# Inline sequences +if ($yaml[6] != array("One", "Two", "Three", "Four")) + die("Sequence 6 failed"); + +# Nested Inline Sequences +if ($yaml[7] != array("One", array("Two", "And", "Three"), "Four", "Five")) + die("Sequence 7 failed"); + +# Nested Nested Inline Sequences +if ($yaml[8] != array( "This", array("Is", "Getting", array("Ridiculous", "Guys")), + "Seriously", array("Show", "Mercy"))) + die("Sequence 8 failed"); + +# Inline mappings +if ($yaml[9] != array("name" => "chris", "age" => "young", "brand" => "lucky strike")) + die("Sequence 9 failed"); + +# Nested inline mappings +if ($yaml[10] != array("name" => "mark", "age" => "older than chris", + "brand" => array("marlboro", "lucky strike"))) + die("Sequence 10 failed"); + +# References -- they're shaky, but functional +if ($yaml['dynamic languages'] != array('Perl', 'Python', 'PHP', 'Ruby')) + die("Key: 'dynamic languages' failed"); + +if ($yaml['compiled languages'] != array('C/C++', 'Java')) + die("Key: 'compiled languages' failed"); + +if ($yaml['all languages'] != array( + array('Perl', 'Python', 'PHP', 'Ruby'), + array('C/C++', 'Java') + )) + die("Key: 'all languages' failed"); + +# Added in .2.2: Escaped quotes +if ($yaml[11] != "you know, this shouldn't work. but it does.") + die("Sequence 11 failed."); + +if ($yaml[12] != "that's my value.") + die("Sequence 12 failed."); + +if ($yaml[13] != "again, that's my value.") + die("Sequence 13 failed."); + +if ($yaml[14] != "here's to \"quotes\", boss.") + die("Sequence 14 failed."); + +if ($yaml[15] != array( 'name' => "Foo, Bar's", 'age' => 20)) + die("Sequence 15 failed."); + +if ($yaml[16] != array( 0 => "a", 1 => array (0 => 1, 1 => 2), 2 => "b")) + die("Sequence 16 failed."); + +if ($yaml['endloop'] != "Does this line in the end indeed make Spyc go to an infinite loop?") + die("[endloop] failed."); + + +print "spyc.yaml parsed correctly\n"; + +?> \ No newline at end of file diff --git a/plugins/vdomah/blogviews/vendor/mustangostang/spyc/phpunit.xml b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/phpunit.xml new file mode 100644 index 000000000..a6151af8e --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/phpunit.xml @@ -0,0 +1,8 @@ + + + + + tests/ + + + diff --git a/plugins/vdomah/blogviews/vendor/mustangostang/spyc/spyc.yaml b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/spyc.yaml new file mode 100644 index 000000000..489f28c9f --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/spyc.yaml @@ -0,0 +1,219 @@ +# +# S P Y C +# a simple php yaml class +# +# authors: [vlad andersen (vlad.andersen@gmail.com), chris wanstrath (chris@ozmm.org)] +# websites: [http://www.yaml.org, http://spyc.sourceforge.net/] +# license: [MIT License, http://www.opensource.org/licenses/mit-license.php] +# copyright: (c) 2005-2006 Chris Wanstrath, 2006-2014 Vlad Andersen +# +# spyc.yaml - A file containing the YAML that Spyc understands. + +--- + +# Mappings - with proper types +String: Anyone's name, really. +Int: 13 +BadHex: f0xf3 +Hex: 0xf3 +True: true +False: false +Zero: 0 +Null: NULL +NotNull: 'null' +NotTrue: 'y' +NotBoolTrue: 'true' +NotInt: '5' +Float: 5.34 +Negative: -90 +SmallFloat: 0.7 +NewLine: \n +QuotedNewLine: "\n" + +# A sequence +- PHP Class +- Basic YAML Loader +- Very Basic YAML Dumper + +# A sequence of a sequence +- + - YAML is so easy to learn. + - Your config files will never be the same. + +# Sequence of mappings +- + cpu: 1.5ghz + ram: 1 gig + os : os x 10.4.1 + +# Mapped sequence +domains: + - yaml.org + - php.net + +# A sequence like this. +- program: Adium + platform: OS X + type: Chat Client + +# A folded block as a mapped value +no time: > + There isn't any time + for your tricks! + + Do you understand? + +# A literal block as a mapped value +some time: | + There is nothing but time + for your tricks. + +# Crazy combinations +databases: + - name: spartan + notes: + - Needs to be backed up + - Needs to be normalized + type: mysql + +# You can be a bit tricky +"if: you'd": like + +# Inline sequences +- [One, Two, Three, Four] + +# Nested Inline Sequences +- [One, [Two, And, Three], Four, Five] + +# Nested Nested Inline Sequences +- [This, [Is, Getting, [Ridiculous, Guys]], Seriously, [Show, Mercy]] + +# Inline mappings +- {name: chris, age: young, brand: lucky strike} + +# Nested inline mappings +- {name: mark, age: older than chris, brand: [marlboro, lucky strike]} + +# References -- they're shaky, but functional +dynamic languages: &DLANGS + - Perl + - Python + - PHP + - Ruby +compiled languages: &CLANGS + - C/C++ + - Java +all languages: + - *DLANGS + - *CLANGS + +# Added in .2.2: Escaped quotes +- you know, this shouldn't work. but it does. +- 'that''s my value.' +- 'again, that\'s my value.' +- "here's to \"quotes\", boss." + +# added in .2.3 +- {name: "Foo, Bar's", age: 20} + +# Added in .2.4: bug [ 1418193 ] Quote Values in Nested Arrays +- [a, ['1', "2"], b] + +# Add in .5.2: Quoted new line values. +- "First line\nSecond line\nThird line" + +# Added in .2.4: malformed YAML +all + javascripts: [dom1.js, dom.js] + +# Added in .2 +1040: Ooo, a numeric key! # And working comments? Wow! Colons in comments: a menace (0.3). + +hash_1: Hash #and a comment +hash_2: "Hash #and a comment" +"hash#3": "Hash (#) can appear in key too" + +float_test: 1.0 +float_test_with_quotes: '1.0' +float_inverse_test: 001 + +a_really_large_number: 115792089237316195423570985008687907853269984665640564039457584007913129639936 # 2^256 + +int array: [ 1, 2, 3 ] + +array on several lines: + [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 ] + +morelesskey: "" + +array_of_zero: [0] +sophisticated_array_of_zero: {rx: {tx: [0]} } + +switches: + - { row: 0, col: 0, func: {tx: [0, 1]} } + +empty_sequence: [ ] +empty_hash: { } + +special_characters: "[{]]{{]]" + +asterisks: "*" + +empty_key: + : + key: value + +trailing_colon: "foo:" + +multiline_items: + - type: SomeItem + values: [blah, blah, blah, + blah] + ints: [2, 54, 12, + 2143] + +many_lines: | + A quick + fox + + + jumped + over + + + + + + a lazy + + + + dog + + +werte: + 1: nummer 1 + 0: Stunde 0 + +noindent_records: +- record1: value1 +- record2: value2 + +"a:1": [1000] +"a:2": + - 2000 +a:3: [3000] + +complex_unquoted_key: + a:b:''test': value + +array with commas: + ["0","1"] + +invoice: ["Something", "", '', "Something else"] +quotes: ['Something', "Nothing", 'Anything', "Thing"] + +# [Endloop] +endloop: | + Does this line in the end indeed make Spyc go to an infinite loop? diff --git a/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/DumpTest.php b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/DumpTest.php new file mode 100644 index 000000000..ceb5c8e5b --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/DumpTest.php @@ -0,0 +1,194 @@ +files_to_test = array (__DIR__.'/../spyc.yaml', 'failing1.yaml', 'indent_1.yaml', 'quotes.yaml'); + } + + public function testShortSyntax() { + $dump = spyc_dump(array ('item1', 'item2', 'item3')); + $awaiting = "- item1\n- item2\n- item3\n"; + $this->assertEquals ($awaiting, $dump); + } + + public function testDump() { + foreach ($this->files_to_test as $file) { + $yaml = spyc_load(file_get_contents($file)); + $dump = Spyc::YAMLDump ($yaml); + $yaml_after_dump = Spyc::YAMLLoad ($dump); + $this->assertEquals ($yaml, $yaml_after_dump); + } + } + + public function testDumpWithQuotes() { + $Spyc = new Spyc(); + $Spyc->setting_dump_force_quotes = true; + foreach ($this->files_to_test as $file) { + $yaml = $Spyc->load(file_get_contents($file)); + $dump = $Spyc->dump ($yaml); + $yaml_after_dump = Spyc::YAMLLoad ($dump); + $this->assertEquals ($yaml, $yaml_after_dump); + } + } + + public function testDumpArrays() { + $dump = Spyc::YAMLDump(array ('item1', 'item2', 'item3')); + $awaiting = "---\n- item1\n- item2\n- item3\n"; + $this->assertEquals ($awaiting, $dump); + } + + public function testNull() { + $dump = Spyc::YAMLDump(array('a' => 1, 'b' => null, 'c' => 3)); + $awaiting = "---\na: 1\nb: null\nc: 3\n"; + $this->assertEquals ($awaiting, $dump); + } + + public function testNext() { + $array = array("aaa", "bbb", "ccc"); + #set arrays internal pointer to next element + next($array); + $dump = Spyc::YAMLDump($array); + $awaiting = "---\n- aaa\n- bbb\n- ccc\n"; + $this->assertEquals ($awaiting, $dump); + } + + public function testDumpingMixedArrays() { + $array = array(); + $array[] = 'Sequence item'; + $array['The Key'] = 'Mapped value'; + $array[] = array('A sequence','of a sequence'); + $array[] = array('first' => 'A sequence','second' => 'of mapped values'); + $array['Mapped'] = array('A sequence','which is mapped'); + $array['A Note'] = 'What if your text is too long?'; + $array['Another Note'] = 'If that is the case, the dumper will probably fold your text by using a block. Kinda like this.'; + $array['The trick?'] = 'The trick is that we overrode the default indent, 2, to 4 and the default wordwrap, 40, to 60.'; + $array['Old Dog'] = "And if you want\n to preserve line breaks, \ngo ahead!"; + $array['key:withcolon'] = "Should support this to"; + + $yaml = Spyc::YAMLDump($array,4,60); + } + + public function testMixed() { + $dump = Spyc::YAMLDump(array(0 => 1, 'b' => 2, 1 => 3)); + $awaiting = "---\n0: 1\nb: 2\n1: 3\n"; + $this->assertEquals ($awaiting, $dump); + } + + public function testDumpNumerics() { + $dump = Spyc::YAMLDump(array ('404', '405', '500')); + $awaiting = "---\n- \"404\"\n- \"405\"\n- \"500\"\n"; + $this->assertEquals ($awaiting, $dump); + } + + public function testDumpAsterisks() { + $dump = Spyc::YAMLDump(array ('*')); + $awaiting = "---\n- '*'\n"; + $this->assertEquals ($awaiting, $dump); + } + + public function testDumpAmpersands() { + $dump = Spyc::YAMLDump(array ('some' => '&foo')); + $awaiting = "---\nsome: '&foo'\n"; + $this->assertEquals ($awaiting, $dump); + } + + public function testDumpExclamations() { + $dump = Spyc::YAMLDump(array ('some' => '!foo')); + $awaiting = "---\nsome: '!foo'\n"; + $this->assertEquals ($awaiting, $dump); + } + + public function testDumpExclamations2() { + $dump = Spyc::YAMLDump(array ('some' => 'foo!')); + $awaiting = "---\nsome: foo!\n"; + $this->assertEquals ($awaiting, $dump); + } + + public function testDumpApostrophes() { + $dump = Spyc::YAMLDump(array ('some' => "'Biz' pimpt bedrijventerreinen")); + $awaiting = "---\nsome: \"'Biz' pimpt bedrijventerreinen\"\n"; + $this->assertEquals ($awaiting, $dump); + } + + public function testDumpNumericHashes() { + $dump = Spyc::YAMLDump(array ("titel"=> array("0" => "", 1 => "Dr.", 5 => "Prof.", 6 => "Prof. Dr."))); + $awaiting = "---\ntitel:\n 0: \"\"\n 1: Dr.\n 5: Prof.\n 6: Prof. Dr.\n"; + $this->assertEquals ($awaiting, $dump); + } + + public function testEmpty() { + $dump = Spyc::YAMLDump(array("foo" => array())); + $awaiting = "---\nfoo: [ ]\n"; + $this->assertEquals ($awaiting, $dump); + } + + public function testHashesInKeys() { + $dump = Spyc::YAMLDump(array ('#color' => '#ffffff')); + $awaiting = "---\n\"#color\": '#ffffff'\n"; + $this->assertEquals ($awaiting, $dump); + } + + public function testParagraph() { + $dump = Spyc::YAMLDump(array ('key' => "|\n value")); + $awaiting = "---\nkey: |\n value\n"; + $this->assertEquals ($awaiting, $dump); + } + + public function testParagraphTwo() { + $dump = Spyc::YAMLDump(array ('key' => 'Congrats, pimpt bedrijventerreinen pimpt bedrijventerreinen pimpt bedrijventerreinen!')); + $awaiting = "---\nkey: >\n Congrats, pimpt bedrijventerreinen pimpt\n bedrijventerreinen pimpt\n bedrijventerreinen!\n"; + $this->assertEquals ($awaiting, $dump); + } + + public function testString() { + $dump = Spyc::YAMLDump(array ('key' => array('key_one' => 'Congrats, pimpt bedrijventerreinen!'))); + $awaiting = "---\nkey:\n key_one: Congrats, pimpt bedrijventerreinen!\n"; + $this->assertEquals ($awaiting, $dump); + } + + public function testStringLong() { + $dump = Spyc::YAMLDump(array ('key' => array('key_one' => 'Congrats, pimpt bedrijventerreinen pimpt bedrijventerreinen pimpt bedrijventerreinen!'))); + $awaiting = "---\nkey:\n key_one: >\n Congrats, pimpt bedrijventerreinen pimpt\n bedrijventerreinen pimpt\n bedrijventerreinen!\n"; + $this->assertEquals ($awaiting, $dump); + } + + public function testStringDoubleQuote() { + $dump = Spyc::YAMLDump(array ('key' => array('key_one' => array('key_two' => '"Système d\'e-réservation"')))); + $awaiting = "---\nkey:\n key_one:\n key_two: |\n Système d'e-réservation\n"; + $this->assertEquals ($awaiting, $dump); + } + + public function testLongStringDoubleQuote() { + $dump = Spyc::YAMLDump(array ('key' => array('key_one' => array('key_two' => '"Système d\'e-réservation bedrijventerreinen pimpt" bedrijventerreinen!')))); + $awaiting = "---\nkey:\n key_one:\n key_two: |\n \"Système d'e-réservation bedrijventerreinen pimpt\" bedrijventerreinen!\n"; + $this->assertEquals ($awaiting, $dump); + } + + public function testStringStartingWithSpace() { + $dump = Spyc::YAMLDump(array ('key' => array('key_one' => " Congrats, pimpt bedrijventerreinen \n pimpt bedrijventerreinen pimpt bedrijventerreinen!"))); + $awaiting = "---\nkey:\n key_one: |\n Congrats, pimpt bedrijventerreinen\n pimpt bedrijventerreinen pimpt bedrijventerreinen!\n"; + $this->assertEquals ($awaiting, $dump); + } + + public function testPerCentOne() { + $dump = Spyc::YAMLDump(array ('key' => "%name%, pimpts bedrijventerreinen!")); + $awaiting = "---\nkey: '%name%, pimpts bedrijventerreinen!'\n"; + $this->assertEquals ($awaiting, $dump); + } + + public function testPerCentAndSimpleQuote() { + $dump = Spyc::YAMLDump(array ('key' => "%name%, pimpt's bedrijventerreinen!")); + $awaiting = "---\nkey: \"%name%, pimpt's bedrijventerreinen!\"\n"; + $this->assertEquals ($awaiting, $dump); + } + + public function testPerCentAndDoubleQuote() { + $dump = Spyc::YAMLDump(array ('key' => '%name%, pimpt\'s "bed"rijventerreinen!')); + $awaiting = "---\nkey: |\n %name%, pimpt's \"bed\"rijventerreinen!\n"; + $this->assertEquals ($awaiting, $dump); + } + +} diff --git a/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/IndentTest.php b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/IndentTest.php new file mode 100644 index 000000000..b7cdcab7d --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/IndentTest.php @@ -0,0 +1,68 @@ +Y = Spyc::YAMLLoad(__DIR__."/indent_1.yaml"); + } + + public function testIndent_1() { + $this->assertEquals (array ('child_1' => 2, 'child_2' => 0, 'child_3' => 1), $this->Y['root']); + } + + public function testIndent_2() { + $this->assertEquals (array ('child_1' => 1, 'child_2' => 2), $this->Y['root2']); + } + + public function testIndent_3() { + $this->assertEquals (array (array ('resolutions' => array (1024 => 768, 1920 => 1200), 'producer' => 'Nec')), $this->Y['display']); + } + + public function testIndent_4() { + $this->assertEquals (array ( + array ('resolutions' => array (1024 => 768)), + array ('resolutions' => array (1920 => 1200)), + ), $this->Y['displays']); + } + + public function testIndent_5() { + $this->assertEquals (array (array ( + 'row' => 0, + 'col' => 0, + 'headsets_affected' => array ( + array ( + 'ports' => array (0), + 'side' => 'left', + ) + ), + 'switch_function' => array ( + 'ics_ptt' => true + ) + )), $this->Y['nested_hashes_and_seqs']); + } + + public function testIndent_6() { + $this->assertEquals (array ( + 'h' => array ( + array ('a' => 'b', 'a1' => 'b1'), + array ('c' => 'd') + ) + ), $this->Y['easier_nest']); + } + + public function testIndent_space() { + $this->assertEquals ("By four\n spaces", $this->Y['one_space']); + } + + public function testListAndComment() { + $this->assertEquals (array ('one', 'two', 'three'), $this->Y['list_and_comment']); + } + + public function testAnchorAndAlias() { + $this->assertEquals (array ('database' => 'rails_dev', 'adapter' => 'mysql', 'host' => 'localhost'), $this->Y['development']); + $this->assertEquals (array (1 => 'abc'), $this->Y['zzz']); + } + +} diff --git a/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/LoadTest.php b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/LoadTest.php new file mode 100644 index 000000000..a25d36fe8 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/LoadTest.php @@ -0,0 +1,17 @@ +assertEquals ($yaml, $yaml_loaded); + } + } +} diff --git a/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/ParseTest.php b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/ParseTest.php new file mode 100644 index 000000000..2ce77ca85 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/ParseTest.php @@ -0,0 +1,413 @@ +yaml = spyc_load_file(__DIR__.'/../spyc.yaml'); + } + + public function testMergeHashKeys() { + $Expected = array ( + array ('step' => array('instrument' => 'Lasik 2000', 'pulseEnergy' => 5.4, 'pulseDuration' => 12, 'repetition' => 1000, 'spotSize' => '1mm')), + array ('step' => array('instrument' => 'Lasik 2000', 'pulseEnergy' => 5.4, 'pulseDuration' => 12, 'repetition' => 1000, 'spotSize' => '2mm')), + ); + $Actual = spyc_load_file (__DIR__.'/indent_1.yaml'); + $this->assertEquals ($Expected, $Actual['steps']); + } + + public function testDeathMasks() { + $Expected = array ('sad' => 2, 'magnificent' => 4); + $Actual = spyc_load_file (__DIR__.'/indent_1.yaml'); + $this->assertEquals ($Expected, $Actual['death masks are']); + } + + public function testDevDb() { + $Expected = array ('adapter' => 'mysql', 'host' => 'localhost', 'database' => 'rails_dev'); + $Actual = spyc_load_file (__DIR__.'/indent_1.yaml'); + $this->assertEquals ($Expected, $Actual['development']); + } + + public function testNumericKey() { + $this->assertEquals ("Ooo, a numeric key!", $this->yaml[1040]); + } + + public function testMappingsString() { + $this->assertEquals ("Anyone's name, really.", $this->yaml['String']); + } + + public function testMappingsInt() { + $this->assertSame (13, $this->yaml['Int']); + } + + public function testMappingsHex() { + $this->assertSame (243, $this->yaml['Hex']); + $this->assertSame ('f0xf3', $this->yaml['BadHex']); + } + + public function testMappingsBooleanTrue() { + $this->assertSame (true, $this->yaml['True']); + } + + public function testMappingsBooleanFalse() { + $this->assertSame (false, $this->yaml['False']); + } + + public function testMappingsZero() { + $this->assertSame (0, $this->yaml['Zero']); + } + + public function testMappingsNull() { + $this->assertSame (null, $this->yaml['Null']); + } + + public function testMappingsNotNull() { + $this->assertSame ('null', $this->yaml['NotNull']); + } + + public function testMappingsFloat() { + $this->assertSame (5.34, $this->yaml['Float']); + } + + public function testMappingsNegative() { + $this->assertSame (-90, $this->yaml['Negative']); + } + + public function testMappingsSmallFloat() { + $this->assertSame (0.7, $this->yaml['SmallFloat']); + } + + public function testNewline() { + $this->assertSame ('\n', $this->yaml['NewLine']); + } + + public function testQuotedNewline() { + $this->assertSame ("\n", $this->yaml['QuotedNewLine']); + } + + public function testSeq0() { + $this->assertEquals ("PHP Class", $this->yaml[0]); + } + + public function testSeq1() { + $this->assertEquals ("Basic YAML Loader", $this->yaml[1]); + } + + public function testSeq2() { + $this->assertEquals ("Very Basic YAML Dumper", $this->yaml[2]); + } + + public function testSeq3() { + $this->assertEquals (array("YAML is so easy to learn.", + "Your config files will never be the same."), $this->yaml[3]); + } + + public function testSeqMap() { + $this->assertEquals (array("cpu" => "1.5ghz", "ram" => "1 gig", + "os" => "os x 10.4.1"), $this->yaml[4]); + } + + public function testMappedSequence() { + $this->assertEquals (array("yaml.org", "php.net"), $this->yaml['domains']); + } + + public function testAnotherSequence() { + $this->assertEquals (array("program" => "Adium", "platform" => "OS X", + "type" => "Chat Client"), $this->yaml[5]); + } + + public function testFoldedBlock() { + $this->assertEquals ("There isn't any time for your tricks!\nDo you understand?", $this->yaml['no time']); + } + + public function testLiteralAsMapped() { + $this->assertEquals ("There is nothing but time\nfor your tricks.", $this->yaml['some time']); + } + + public function testCrazy() { + $this->assertEquals (array( array("name" => "spartan", "notes" => + array( "Needs to be backed up", + "Needs to be normalized" ), + "type" => "mysql" )), $this->yaml['databases']); + } + + public function testColons() { + $this->assertEquals ("like", $this->yaml["if: you'd"]); + } + + public function testInline() { + $this->assertEquals (array("One", "Two", "Three", "Four"), $this->yaml[6]); + } + + public function testNestedInline() { + $this->assertEquals (array("One", array("Two", "And", "Three"), "Four", "Five"), $this->yaml[7]); + } + + public function testNestedNestedInline() { + $this->assertEquals (array( "This", array("Is", "Getting", array("Ridiculous", "Guys")), + "Seriously", array("Show", "Mercy")), $this->yaml[8]); + } + + public function testInlineMappings() { + $this->assertEquals (array("name" => "chris", "age" => "young", "brand" => "lucky strike"), $this->yaml[9]); + } + + public function testNestedInlineMappings() { + $this->assertEquals (array("name" => "mark", "age" => "older than chris", + "brand" => array("marlboro", "lucky strike")), $this->yaml[10]); + } + + public function testReferences() { + $this->assertEquals (array('Perl', 'Python', 'PHP', 'Ruby'), $this->yaml['dynamic languages']); + } + + public function testReferences2() { + $this->assertEquals (array('C/C++', 'Java'), $this->yaml['compiled languages']); + } + + public function testReferences3() { + $this->assertEquals (array( + array('Perl', 'Python', 'PHP', 'Ruby'), + array('C/C++', 'Java') + ), $this->yaml['all languages']); + } + + public function testEscapedQuotes() { + $this->assertEquals ("you know, this shouldn't work. but it does.", $this->yaml[11]); + } + + public function testEscapedQuotes_2() { + $this->assertEquals ( "that's my value.", $this->yaml[12]); + } + + public function testEscapedQuotes_3() { + $this->assertEquals ("again, that's my value.", $this->yaml[13]); + } + + public function testQuotes() { + $this->assertEquals ("here's to \"quotes\", boss.", $this->yaml[14]); + } + + public function testQuoteSequence() { + $this->assertEquals ( array( 'name' => "Foo, Bar's", 'age' => 20), $this->yaml[15]); + } + + public function testShortSequence() { + $this->assertEquals (array( 0 => "a", 1 => array (0 => 1, 1 => 2), 2 => "b"), $this->yaml[16]); + } + + public function testQuotedNewlines() { + $this->assertEquals ("First line\nSecond line\nThird line", $this->yaml[17]); + } + + public function testHash_1() { + $this->assertEquals ("Hash", $this->yaml['hash_1']); + } + + public function testHash_2() { + $this->assertEquals ('Hash #and a comment', $this->yaml['hash_2']); + } + + public function testHash_3() { + $this->assertEquals ('Hash (#) can appear in key too', $this->yaml['hash#3']); + } + + public function testEndloop() { + $this->assertEquals ("Does this line in the end indeed make Spyc go to an infinite loop?", $this->yaml['endloop']); + } + + public function testReallyLargeNumber() { + $this->assertEquals ('115792089237316195423570985008687907853269984665640564039457584007913129639936', $this->yaml['a_really_large_number']); + } + + public function testFloatWithZeros() { + $this->assertSame ('1.0', $this->yaml['float_test']); + } + + public function testFloatWithQuotes() { + $this->assertSame ('1.0', $this->yaml['float_test_with_quotes']); + } + + public function testFloatInverse() { + $this->assertEquals ('001', $this->yaml['float_inverse_test']); + } + + public function testIntArray() { + $this->assertEquals (array (1, 2, 3), $this->yaml['int array']); + } + + public function testArrayOnSeveralLines() { + $this->assertEquals (array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19), $this->yaml['array on several lines']); + } + + public function testArrayWithCommas() { + $this->assertEquals(array (0, 1), $this->yaml['array with commas']); + } + + public function testmoreLessKey() { + $this->assertEquals ('', $this->yaml['morelesskey']); + } + + public function testArrayOfZero() { + $this->assertSame (array(0), $this->yaml['array_of_zero']); + } + + public function testSophisticatedArrayOfZero() { + $this->assertSame (array('rx' => array ('tx' => array (0))), $this->yaml['sophisticated_array_of_zero']); + } + + public function testSwitches() { + $this->assertEquals (array (array ('row' => 0, 'col' => 0, 'func' => array ('tx' => array(0, 1)))), $this->yaml['switches']); + } + + public function testEmptySequence() { + $this->assertSame (array(), $this->yaml['empty_sequence']); + } + + public function testEmptyHash() { + $this->assertSame (array(), $this->yaml['empty_hash']); + } + + public function testEmptykey() { + $this->assertSame (array('' => array ('key' => 'value')), $this->yaml['empty_key']); + } + + public function testMultilines() { + $this->assertSame (array(array('type' => 'SomeItem', 'values' => array ('blah', 'blah', 'blah', 'blah'), 'ints' => array(2, 54, 12, 2143))), $this->yaml['multiline_items']); + } + + public function testManyNewlines() { + $this->assertSame ('A quick +fox + + +jumped +over + + + + + +a lazy + + + +dog', $this->yaml['many_lines']); + } + + public function testWerte() { + $this->assertSame (array ('1' => 'nummer 1', '0' => 'Stunde 0'), $this->yaml['werte']); + } + + /* public function testNoIndent() { + $this->assertSame (array( + array ('record1'=>'value1'), + array ('record2'=>'value2') + ) + , $this->yaml['noindent_records']); + } */ + + public function testColonsInKeys() { + $this->assertSame (array (1000), $this->yaml['a:1']); + } + + public function testColonsInKeys2() { + $this->assertSame (array (2000), $this->yaml['a:2']); + } + + public function testUnquotedColonsInKeys() { + $this->assertSame (array (3000), $this->yaml['a:3']); + } + + public function testComplicatedKeyWithColon() { + $this->assertSame(array("a:b:''test'" => 'value'), $this->yaml['complex_unquoted_key']); + } + + public function testKeysInMappedValueException() { + $this->setExpectedException('Exception'); + Spyc::YAMLLoad('x: y: z:'); + } + + public function testKeysInValueException() { + $this->setExpectedException('Exception'); + Spyc::YAMLLoad('x: y: z'); + } + + public function testSpecialCharacters() { + $this->assertSame ('[{]]{{]]', $this->yaml['special_characters']); + } + + public function testAngleQuotes() { + $Quotes = Spyc::YAMLLoad(__DIR__.'/quotes.yaml'); + $this->assertEquals (array ('html_tags' => array ('
', '

'), 'html_content' => array ('

hello world

', 'hello
world'), 'text_content' => array ('hello world')), + $Quotes); + } + + public function testFailingColons() { + $Failing = Spyc::YAMLLoad(__DIR__.'/failing1.yaml'); + $this->assertSame (array ('MyObject' => array ('Prop1' => array ('key1:val1'))), + $Failing); + } + + public function testQuotesWithComments() { + $Expected = 'bar'; + $Actual = spyc_load_file (__DIR__.'/comments.yaml'); + $this->assertEquals ($Expected, $Actual['foo']); + } + + public function testArrayWithComments() { + $Expected = array ('x', 'y', 'z'); + $Actual = spyc_load_file (__DIR__.'/comments.yaml'); + $this->assertEquals ($Expected, $Actual['arr']); + } + + public function testAfterArrayWithKittens() { + $Expected = 'kittens'; + $Actual = spyc_load_file (__DIR__.'/comments.yaml'); + $this->assertEquals ($Expected, $Actual['bar']); + } + + // Plain characters http://www.yaml.org/spec/1.2/spec.html#id2789510 + public function testKai() { + $Expected = array('-example' => 'value'); + $Actual = spyc_load_file (__DIR__.'/indent_1.yaml'); + $this->assertEquals ($Expected, $Actual['kai']); + } + + public function testKaiList() { + $Expected = array ('-item', '-item', '-item'); + $Actual = spyc_load_file (__DIR__.'/indent_1.yaml'); + $this->assertEquals ($Expected, $Actual['kai_list_of_items']); + } + + public function testDifferentQuoteTypes() { + $expected = array ('Something', "", "", "Something else"); + $this->assertSame ($expected, $this->yaml['invoice']); + } + + public function testDifferentQuoteTypes2() { + $expected = array ('Something', "Nothing", "Anything", "Thing"); + $this->assertSame ($expected, $this->yaml['quotes']); + } + + // Separation spaces http://www.yaml.org/spec/1.2/spec.html#id2778394 + public function testMultipleArrays() { + $expected = array(array(array('x'))); + $this->assertSame($expected, Spyc::YAMLLoad("- - - x")); + } + + public function testElementWithEmptyHash() + { + $element = "hash: {}\narray: []"; + $yaml = Spyc::YAMLLoadString($element); + $this->assertEquals($yaml['hash'], []); + $this->assertEquals($yaml['array'], []); + + $yaml = Spyc::YAMLLoadString($element, [ + 'setting_empty_hash_as_object' => true + ]); + $this->assertInstanceOf(stdClass::class, $yaml['hash']); + $this->assertEquals($yaml['array'], []); + } +} diff --git a/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/RoundTripTest.php b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/RoundTripTest.php new file mode 100644 index 000000000..3e707dfe8 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/RoundTripTest.php @@ -0,0 +1,76 @@ + $a))); } + + +class RoundTripTest extends PHPUnit_Framework_TestCase { + + protected function setUp() { + } + + public function testNull() { + $this->assertEquals (array ('x' => null), roundTrip (null)); + } + + public function testY() { + $this->assertEquals (array ('x' => 'y'), roundTrip ('y')); + } + + public function testExclam() { + $this->assertEquals (array ('x' => '!yeah'), roundTrip ('!yeah')); + } + + public function test5() { + $this->assertEquals (array ('x' => '5'), roundTrip ('5')); + } + + public function testSpaces() { + $this->assertEquals (array ('x' => 'x '), roundTrip ('x ')); + } + + public function testApostrophes() { + $this->assertEquals (array ('x' => "'biz'"), roundTrip ("'biz'")); + } + + public function testNewLines() { + $this->assertEquals (array ('x' => "\n"), roundTrip ("\n")); + } + + public function testHashes() { + $this->assertEquals (array ('x' => array ("#color" => '#fff')), roundTrip (array ("#color" => '#fff'))); + } + + public function testPreserveString() { + $result1 = roundTrip ('0'); + $result2 = roundTrip ('true'); + $this->assertTrue (is_string ($result1['x'])); + $this->assertTrue (is_string ($result2['x'])); + } + + public function testPreserveBool() { + $result = roundTrip (true); + $this->assertTrue (is_bool ($result['x'])); + } + + public function testPreserveInteger() { + $result = roundTrip (0); + $this->assertTrue (is_int ($result['x'])); + } + + public function testWordWrap() { + $this->assertEquals (array ('x' => "aaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"), roundTrip ("aaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")); + } + + public function testABCD() { + $this->assertEquals (array ('a', 'b', 'c', 'd'), Spyc::YAMLLoad(Spyc::YAMLDump(array('a', 'b', 'c', 'd')))); + } + + public function testABCD2() { + $a = array('a', 'b', 'c', 'd'); // Create a simple list + $b = Spyc::YAMLDump($a); // Dump the list as YAML + $c = Spyc::YAMLLoad($b); // Load the dumped YAML + $d = Spyc::YAMLDump($c); // Re-dump the data + $this->assertSame($b, $d); + } + +} diff --git a/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/comments.yaml b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/comments.yaml new file mode 100644 index 000000000..c05012f3d --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/comments.yaml @@ -0,0 +1,3 @@ +foo: 'bar' #Comment +arr: ['x', 'y', 'z'] # Comment here +bar: kittens \ No newline at end of file diff --git a/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/failing1.yaml b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/failing1.yaml new file mode 100644 index 000000000..6906a51c1 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/failing1.yaml @@ -0,0 +1,2 @@ +MyObject: + Prop1: {key1:val1} \ No newline at end of file diff --git a/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/indent_1.yaml b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/indent_1.yaml new file mode 100644 index 000000000..62d6ece93 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/indent_1.yaml @@ -0,0 +1,70 @@ +root: + child_1: 2 + + child_2: 0 + child_3: 1 + +root2: + child_1: 1 +# A comment + child_2: 2 + +displays: + - resolutions: + 1024: 768 + - resolutions: + 1920: 1200 + +display: + - resolutions: + 1024: 768 + 1920: 1200 + producer: "Nec" + +nested_hashes_and_seqs: + - { row: 0, col: 0, headsets_affected: [{ports: [0], side: left}], switch_function: {ics_ptt: true} } + +easier_nest: { h: [{a: b, a1: b1}, {c: d}] } + +one_space: | + By four + spaces + +steps: + - step: &id001 + instrument: Lasik 2000 + pulseEnergy: 5.4 + pulseDuration: 12 + repetition: 1000 + spotSize: 1mm + - step: + <<: *id001 + spotSize: 2mm + +death masks are: + sad: 2 + <<: {magnificent: 4} + +login: &login + adapter: mysql + host: localhost + +development: + database: rails_dev + <<: *login + +"key": "value:" +colon_only: ":" + +list_and_comment: [one, two, three] # comment +kai: + -example: value +kai_list_of_items: + - -item + - '-item' + -item + +&foo bar: + 1: "abc" + +zzz: *foo diff --git a/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/quotes.yaml b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/quotes.yaml new file mode 100644 index 000000000..2ceea86aa --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/mustangostang/spyc/tests/quotes.yaml @@ -0,0 +1,8 @@ +html_tags: + -
+ -

+html_content: + -

hello world

+ - hello
world +text_content: + - hello world \ No newline at end of file diff --git a/plugins/vdomah/blogviews/vendor/piwik/device-detector/Cache/Cache.php b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Cache/Cache.php new file mode 100644 index 000000000..fcdc5e99f --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Cache/Cache.php @@ -0,0 +1,22 @@ +cache = $cache; + } + + /** + * @inheritDoc + */ + public function fetch($id) + { + return $this->cache->get($id, false); + } + + /** + * @inheritDoc + */ + public function contains($id) + { + return $this->cache->has($id); + } + + /** + * @inheritDoc + */ + public function save($id, $data, $lifeTime = 0) + { + return $this->cache->set($id, $data, func_num_args() < 3 ? null : $lifeTime); + } + + /** + * @inheritDoc + */ + public function delete($id) + { + return $this->cache->delete($id); + } + + /** + * @inheritDoc + */ + public function flushAll() + { + return $this->cache->clear(); + } +} diff --git a/plugins/vdomah/blogviews/vendor/piwik/device-detector/Cache/PSR6Bridge.php b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Cache/PSR6Bridge.php new file mode 100644 index 000000000..2d2ebca19 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Cache/PSR6Bridge.php @@ -0,0 +1,68 @@ +pool = $pool; + } + + /** + * @inheritDoc + */ + public function fetch($id) + { + $item = $this->pool->getItem($id); + return $item->isHit() ? $item->get() : false; + } + + /** + * @inheritDoc + */ + public function contains($id) + { + return $this->pool->hasItem($id); + } + + /** + * @inheritDoc + */ + public function save($id, $data, $lifeTime = 0) + { + $item = $this->pool->getItem($id); + $item->set($data); + if (func_num_args() > 2) { + $item->expiresAfter($lifeTime); + } + return $this->pool->save($item); + } + + /** + * @inheritDoc + */ + public function delete($id) + { + return $this->pool->deleteItem($id); + } + + /** + * @inheritDoc + */ + public function flushAll() + { + return $this->pool->clear(); + } +} diff --git a/plugins/vdomah/blogviews/vendor/piwik/device-detector/Cache/StaticCache.php b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Cache/StaticCache.php new file mode 100644 index 000000000..23a38c6d1 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Cache/StaticCache.php @@ -0,0 +1,53 @@ +contains($id) ? self::$staticCache[$id] : false; + } + + public function contains($id) + { + return isset(self::$staticCache[$id]) || array_key_exists($id, self::$staticCache); + } + + public function save($id, $data, $lifeTime = 0) + { + self::$staticCache[$id] = $data; + return true; + } + + public function delete($id) + { + unset(self::$staticCache[$id]); + return true; + } + + public function flushAll() + { + self::$staticCache = array(); + return true; + } +} diff --git a/plugins/vdomah/blogviews/vendor/piwik/device-detector/DeviceDetector.php b/plugins/vdomah/blogviews/vendor/piwik/device-detector/DeviceDetector.php new file mode 100644 index 000000000..39636a2cc --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/piwik/device-detector/DeviceDetector.php @@ -0,0 +1,895 @@ +setUserAgent($userAgent); + } + + $this->addClientParser('FeedReader'); + $this->addClientParser('MobileApp'); + $this->addClientParser('MediaPlayer'); + $this->addClientParser('PIM'); + $this->addClientParser('Browser'); + $this->addClientParser('Library'); + + $this->addDeviceParser('HbbTv'); + $this->addDeviceParser('Console'); + $this->addDeviceParser('CarBrowser'); + $this->addDeviceParser('Camera'); + $this->addDeviceParser('PortableMediaPlayer'); + $this->addDeviceParser('Mobile'); + + $this->addBotParser(new Bot()); + } + + public function __call($methodName, $arguments) + { + foreach (DeviceParserAbstract::getAvailableDeviceTypes() as $deviceName => $deviceType) { + if (strtolower($methodName) == 'is' . strtolower(str_replace(' ', '', $deviceName))) { + return $this->getDevice() == $deviceType; + } + } + + foreach (self::$clientTypes as $client) { + if (strtolower($methodName) == 'is' . strtolower(str_replace(' ', '', $client))) { + return $this->getClient('type') == $client; + } + } + + throw new \BadMethodCallException("Method $methodName not found"); + } + + /** + * Sets the useragent to be parsed + * + * @param string $userAgent + */ + public function setUserAgent($userAgent) + { + if ($this->userAgent != $userAgent) { + $this->reset(); + } + $this->userAgent = $userAgent; + } + + protected function reset() + { + $this->bot = null; + $this->client = null; + $this->device = null; + $this->os = null; + $this->brand = ''; + $this->model = ''; + $this->parsed = false; + } + + /** + * @param ClientParserAbstract|string $parser + * @throws \Exception + */ + public function addClientParser($parser) + { + if (is_string($parser) && class_exists('DeviceDetector\\Parser\\Client\\' . $parser)) { + $className = 'DeviceDetector\\Parser\\Client\\' . $parser; + $parser = new $className(); + } + + if ($parser instanceof ClientParserAbstract) { + $this->clientParsers[] = $parser; + self::$clientTypes[] = $parser->getName(); + return; + } + + throw new \Exception('client parser not found'); + } + + public function getClientParsers() + { + return $this->clientParsers; + } + + /** + * @param DeviceParserAbstract|string $parser + * @throws \Exception + */ + public function addDeviceParser($parser) + { + if (is_string($parser) && class_exists('DeviceDetector\\Parser\\Device\\' . $parser)) { + $className = 'DeviceDetector\\Parser\\Device\\' . $parser; + $parser = new $className(); + } + + if ($parser instanceof DeviceParserAbstract) { + $this->deviceParsers[] = $parser; + return; + } + + throw new \Exception('device parser not found'); + } + + public function getDeviceParsers() + { + return $this->deviceParsers; + } + + /** + * @param BotParserAbstract $parser + */ + public function addBotParser(BotParserAbstract $parser) + { + $this->botParsers[] = $parser; + } + + public function getBotParsers() + { + return $this->botParsers; + } + + /** + * Sets whether to discard additional bot information + * If information is discarded it's only possible check whether UA was detected as bot or not. + * (Discarding information speeds up the detection a bit) + * + * @param bool $discard + */ + public function discardBotInformation($discard = true) + { + $this->discardBotInformation = $discard; + } + + /** + * Sets whether to skip bot detection. + * It is needed if we want bots to be processed as a simple clients. So we can detect if it is mobile client, + * or desktop, or enything else. By default all this information is not retrieved for the bots. + * + * @param bool $skip + */ + public function skipBotDetection($skip = true) + { + $this->skipBotDetection = $skip; + } + + /** + * Returns if the parsed UA was identified as a Bot + * + * @see bots.yml for a list of detected bots + * + * @return bool + */ + public function isBot() + { + return !empty($this->bot); + } + + /** + * Returns if the parsed UA was identified as a touch enabled device + * + * Note: That only applies to windows 8 tablets + * + * @return bool + */ + public function isTouchEnabled() + { + $regex = 'Touch'; + return !!$this->matchUserAgent($regex); + } + + /** + * Returns if the parsed UA contains the 'Android; Tablet;' fragment + * + * @return bool + */ + protected function hasAndroidTableFragment() + { + $regex = 'Android( [\.0-9]+)?; Tablet;'; + return !!$this->matchUserAgent($regex); + } + + /** + * Returns if the parsed UA contains the 'Android; Mobile;' fragment + * + * @return bool + */ + protected function hasAndroidMobileFragment() + { + $regex = 'Android( [\.0-9]+)?; Mobile;'; + return !!$this->matchUserAgent($regex); + } + + protected function usesMobileBrowser() + { + return $this->getClient('type') == 'browser' && Browser::isMobileOnlyBrowser($this->getClient('short_name')); + } + + public function isMobile() + { + // Mobile device types + if (!empty($this->device) && in_array($this->device, array( + DeviceParserAbstract::DEVICE_TYPE_FEATURE_PHONE, + DeviceParserAbstract::DEVICE_TYPE_SMARTPHONE, + DeviceParserAbstract::DEVICE_TYPE_TABLET, + DeviceParserAbstract::DEVICE_TYPE_PHABLET, + DeviceParserAbstract::DEVICE_TYPE_CAMERA, + DeviceParserAbstract::DEVICE_TYPE_PORTABLE_MEDIA_PAYER, + )) + ) { + return true; + } + + // non mobile device types + if (!empty($this->device) && in_array($this->device, array( + DeviceParserAbstract::DEVICE_TYPE_TV, + DeviceParserAbstract::DEVICE_TYPE_SMART_DISPLAY, + DeviceParserAbstract::DEVICE_TYPE_CONSOLE + )) + ) { + return false; + } + + // Check for browsers available for mobile devices only + if ($this->usesMobileBrowser()) { + return true; + } + + $osShort = $this->getOs('short_name'); + if (empty($osShort) || self::UNKNOWN == $osShort) { + return false; + } + + return !$this->isBot() && !$this->isDesktop(); + } + + /** + * Returns if the parsed UA was identified as desktop device + * Desktop devices are all devices with an unknown type that are running a desktop os + * + * @see self::$desktopOsArray + * + * @return bool + */ + public function isDesktop() + { + $osShort = $this->getOs('short_name'); + if (empty($osShort) || self::UNKNOWN == $osShort) { + return false; + } + + // Check for browsers available for mobile devices only + if ($this->usesMobileBrowser()) { + return false; + } + + $decodedFamily = OperatingSystem::getOsFamily($osShort); + + return in_array($decodedFamily, self::$desktopOsArray); + } + + /** + * Returns the operating system data extracted from the parsed UA + * + * If $attr is given only that property will be returned + * + * @param string $attr property to return(optional) + * + * @return array|string + */ + public function getOs($attr = '') + { + if ($attr == '') { + return $this->os; + } + + if (!isset($this->os[$attr])) { + return self::UNKNOWN; + } + + return $this->os[$attr]; + } + + /** + * Returns the client data extracted from the parsed UA + * + * If $attr is given only that property will be returned + * + * @param string $attr property to return(optional) + * + * @return array|string + */ + public function getClient($attr = '') + { + if ($attr == '') { + return $this->client; + } + + if (!isset($this->client[$attr])) { + return self::UNKNOWN; + } + + return $this->client[$attr]; + } + + /** + * Returns the device type extracted from the parsed UA + * + * @see DeviceParserAbstract::$deviceTypes for available device types + * + * @return int|null + */ + public function getDevice() + { + return $this->device; + } + + /** + * Returns the device type extracted from the parsed UA + * + * @see DeviceParserAbstract::$deviceTypes for available device types + * + * @return string + */ + public function getDeviceName() + { + if ($this->getDevice() !== null) { + return DeviceParserAbstract::getDeviceName($this->getDevice()); + } + + return ''; + } + + /** + * Returns the device brand extracted from the parsed UA + * + * @see self::$deviceBrand for available device brands + * + * @return string + */ + public function getBrand() + { + return $this->brand; + } + + /** + * Returns the full device brand name extracted from the parsed UA + * + * @see self::$deviceBrand for available device brands + * + * @return string + */ + public function getBrandName() + { + return DeviceParserAbstract::getFullName($this->getBrand()); + } + + /** + * Returns the device model extracted from the parsed UA + * + * @return string + */ + public function getModel() + { + return $this->model; + } + + /** + * Returns the user agent that is set to be parsed + * + * @return string + */ + public function getUserAgent() + { + return $this->userAgent; + } + + /** + * Returns the bot extracted from the parsed UA + * + * @return array + */ + public function getBot() + { + return $this->bot; + } + + /** + * Returns true, if userAgent was already parsed with parse() + * + * @return bool + */ + public function isParsed() + { + return $this->parsed; + } + + /** + * Triggers the parsing of the current user agent + */ + public function parse() + { + if ($this->isParsed()) { + return; + } + + $this->parsed = true; + + // skip parsing for empty useragents or those not containing any letter + if (empty($this->userAgent) || !preg_match('/([a-z])/i', $this->userAgent)) { + return; + } + + $this->parseBot(); + if ($this->isBot()) { + return; + } + + $this->parseOs(); + + /** + * Parse Clients + * Clients might be browsers, Feed Readers, Mobile Apps, Media Players or + * any other application accessing with an parseable UA + */ + $this->parseClient(); + + $this->parseDevice(); + } + + /** + * Parses the UA for bot information using the Bot parser + */ + protected function parseBot() + { + if ($this->skipBotDetection) { + $this->bot = false; + return false; + } + + $parsers = $this->getBotParsers(); + + foreach ($parsers as $parser) { + $parser->setUserAgent($this->getUserAgent()); + $parser->setYamlParser($this->getYamlParser()); + $parser->setCache($this->getCache()); + if ($this->discardBotInformation) { + $parser->discardDetails(); + } + $bot = $parser->parse(); + if (!empty($bot)) { + $this->bot = $bot; + break; + } + } + } + + + protected function parseClient() + { + $parsers = $this->getClientParsers(); + + foreach ($parsers as $parser) { + $parser->setYamlParser($this->getYamlParser()); + $parser->setCache($this->getCache()); + $parser->setUserAgent($this->getUserAgent()); + $client = $parser->parse(); + if (!empty($client)) { + $this->client = $client; + break; + } + } + } + + protected function parseDevice() + { + $parsers = $this->getDeviceParsers(); + + foreach ($parsers as $parser) { + $parser->setYamlParser($this->getYamlParser()); + $parser->setCache($this->getCache()); + $parser->setUserAgent($this->getUserAgent()); + if ($parser->parse()) { + $this->device = $parser->getDeviceType(); + $this->model = $parser->getModel(); + $this->brand = $parser->getBrand(); + break; + } + } + + /** + * If no brand has been assigned try to match by known vendor fragments + */ + if (empty($this->brand)) { + $vendorParser = new VendorFragment($this->getUserAgent()); + $vendorParser->setYamlParser($this->getYamlParser()); + $vendorParser->setCache($this->getCache()); + $this->brand = $vendorParser->parse(); + } + + $osShortName = $this->getOs('short_name'); + $osFamily = OperatingSystem::getOsFamily($osShortName); + $osVersion = $this->getOs('version'); + $clientName = $this->getClient('name'); + + /** + * Assume all devices running iOS / Mac OS are from Apple + */ + if (empty($this->brand) && in_array($osShortName, array('ATV', 'IOS', 'MAC'))) { + $this->brand = 'AP'; + } + + /** + * Chrome on Android passes the device type based on the keyword 'Mobile' + * If it is present the device should be a smartphone, otherwise it's a tablet + * See https://developer.chrome.com/multidevice/user-agent#chrome_for_android_user_agent + */ + if (is_null($this->device) && $osFamily == 'Android' && Browser::getBrowserFamily($this->getClient('short_name')) == 'Chrome') { + if ($this->matchUserAgent('Chrome/[\.0-9]* Mobile')) { + $this->device = DeviceParserAbstract::DEVICE_TYPE_SMARTPHONE; + } else if ($this->matchUserAgent('Chrome/[\.0-9]* (?!Mobile)')) { + $this->device = DeviceParserAbstract::DEVICE_TYPE_TABLET; + } + } + + /** + * Some user agents simply contain the fragment 'Android; Tablet;' or 'Opera Tablet', so we assume those devices as tablets + */ + if (is_null($this->device) && ($this->hasAndroidTableFragment() || $this->matchUserAgent('Opera Tablet'))) { + $this->device = DeviceParserAbstract::DEVICE_TYPE_TABLET; + } + + /** + * Some user agents simply contain the fragment 'Android; Mobile;', so we assume those devices as smartphones + */ + if (is_null($this->device) && $this->hasAndroidMobileFragment()) { + $this->device = DeviceParserAbstract::DEVICE_TYPE_SMARTPHONE; + } + + /** + * Android up to 3.0 was designed for smartphones only. But as 3.0, which was tablet only, was published + * too late, there were a bunch of tablets running with 2.x + * With 4.0 the two trees were merged and it is for smartphones and tablets + * + * So were are expecting that all devices running Android < 2 are smartphones + * Devices running Android 3.X are tablets. Device type of Android 2.X and 4.X+ are unknown + */ + if (is_null($this->device) && $osShortName == 'AND' && $osVersion != '') { + if (version_compare($osVersion, '2.0') == -1) { + $this->device = DeviceParserAbstract::DEVICE_TYPE_SMARTPHONE; + } elseif (version_compare($osVersion, '3.0') >= 0 and version_compare($osVersion, '4.0') == -1) { + $this->device = DeviceParserAbstract::DEVICE_TYPE_TABLET; + } + } + + /** + * All detected feature phones running android are more likely a smartphone + */ + if ($this->device == DeviceParserAbstract::DEVICE_TYPE_FEATURE_PHONE && $osFamily == 'Android') { + $this->device = DeviceParserAbstract::DEVICE_TYPE_SMARTPHONE; + } + + /** + * According to http://msdn.microsoft.com/en-us/library/ie/hh920767(v=vs.85).aspx + * Internet Explorer 10 introduces the "Touch" UA string token. If this token is present at the end of the + * UA string, the computer has touch capability, and is running Windows 8 (or later). + * This UA string will be transmitted on a touch-enabled system running Windows 8 (RT) + * + * As most touch enabled devices are tablets and only a smaller part are desktops/notebooks we assume that + * all Windows 8 touch devices are tablets. + */ + + if (is_null($this->device) && ($osShortName == 'WRT' || ($osShortName == 'WIN' && version_compare($osVersion, '8') >= 0)) && $this->isTouchEnabled()) { + $this->device = DeviceParserAbstract::DEVICE_TYPE_TABLET; + } + + /** + * All devices running Opera TV Store are assumed to be a tv + */ + if ($this->matchUserAgent('Opera TV Store')) { + $this->device = DeviceParserAbstract::DEVICE_TYPE_TV; + } + + /** + * Devices running Kylo or Espital TV Browsers are assumed to be a TV + */ + if (is_null($this->device) && in_array($clientName, array('Kylo', 'Espial TV Browser'))) { + $this->device = DeviceParserAbstract::DEVICE_TYPE_TV; + } + + // set device type to desktop for all devices running a desktop os that were not detected as an other device type + if (is_null($this->device) && $this->isDesktop()) { + $this->device = DeviceParserAbstract::DEVICE_TYPE_DESKTOP; + } + } + + protected function parseOs() + { + $osParser = new OperatingSystem(); + $osParser->setUserAgent($this->getUserAgent()); + $osParser->setYamlParser($this->getYamlParser()); + $osParser->setCache($this->getCache()); + $this->os = $osParser->parse(); + } + + protected function matchUserAgent($regex) + { + $regex = '/(?:^|[^A-Z_-])(?:' . str_replace('/', '\/', $regex) . ')/i'; + + if (preg_match($regex, $this->userAgent, $matches)) { + return $matches; + } + + return false; + } + + /** + * Parses a useragent and returns the detected data + * + * ATTENTION: Use that method only for testing or very small applications + * To get fast results from DeviceDetector you need to make your own implementation, + * that should use one of the caching mechanisms. See README.md for more information. + * + * @internal + * @deprecated + * + * @param string $ua UserAgent to parse + * + * @return array + */ + public static function getInfoFromUserAgent($ua) + { + $deviceDetector = new DeviceDetector($ua); + $deviceDetector->parse(); + + if ($deviceDetector->isBot()) { + return array( + 'user_agent' => $deviceDetector->getUserAgent(), + 'bot' => $deviceDetector->getBot() + ); + } + + $osFamily = OperatingSystem::getOsFamily($deviceDetector->getOs('short_name')); + $browserFamily = \DeviceDetector\Parser\Client\Browser::getBrowserFamily($deviceDetector->getClient('short_name')); + + $processed = array( + 'user_agent' => $deviceDetector->getUserAgent(), + 'os' => $deviceDetector->getOs(), + 'client' => $deviceDetector->getClient(), + 'device' => array( + 'type' => $deviceDetector->getDeviceName(), + 'brand' => $deviceDetector->getBrand(), + 'model' => $deviceDetector->getModel(), + ), + 'os_family' => $osFamily !== false ? $osFamily : 'Unknown', + 'browser_family' => $browserFamily !== false ? $browserFamily : 'Unknown', + ); + return $processed; + } + + /** + * Sets the Cache class + * + * @param Cache|\Doctrine\Common\Cache\CacheProvider $cache + * @throws \Exception + */ + public function setCache($cache) + { + if ($cache instanceof Cache || + (class_exists('\Doctrine\Common\Cache\CacheProvider') && $cache instanceof \Doctrine\Common\Cache\CacheProvider) + ) { + $this->cache = $cache; + return; + } + + throw new \Exception('Cache not supported'); + } + + /** + * Returns Cache object + * + * @return \Doctrine\Common\Cache\CacheProvider + */ + public function getCache() + { + if (!empty($this->cache)) { + return $this->cache; + } + + return new StaticCache(); + } + + /** + * Sets the Yaml Parser class + * + * @param YamlParser + * @throws \Exception + */ + public function setYamlParser($yamlParser) + { + if ($yamlParser instanceof YamlParser) { + $this->yamlParser = $yamlParser; + return; + } + + throw new \Exception('Yaml Parser not supported'); + } + + /** + * Returns Yaml Parser object + * + * @return YamlParser + */ + public function getYamlParser() + { + if (!empty($this->yamlParser)) { + return $this->yamlParser; + } + + return new Spyc(); + } +} diff --git a/plugins/vdomah/blogviews/vendor/piwik/device-detector/LICENSE b/plugins/vdomah/blogviews/vendor/piwik/device-detector/LICENSE new file mode 100644 index 000000000..0a041280b --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/piwik/device-detector/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + 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 that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU 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 as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Bot.php b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Bot.php new file mode 100644 index 000000000..cfa845ea5 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Bot.php @@ -0,0 +1,70 @@ +discardDetails = true; + } + + /** + * Parses the current UA and checks whether it contains bot information + * + * @see bots.yml for list of detected bots + * + * Step 1: Build a big regex containing all regexes and match UA against it + * -> If no matches found: return + * -> Otherwise: + * Step 2: Walk through the list of regexes in bots.yml and try to match every one + * -> Return the matched data + * + * If $discardDetails is set to TRUE, the Step 2 will be skipped + * $bot will be set to TRUE instead + * + * NOTE: Doing the big match before matching every single regex speeds up the detection + */ + public function parse() + { + $result = null; + + if ($this->preMatchOverall()) { + if ($this->discardDetails) { + $result = true; + } else { + foreach ($this->getRegexes() as $regex) { + $matches = $this->matchUserAgent($regex['regex']); + if ($matches) { + unset($regex['regex']); + $result = $regex; + break; + } + } + } + } + + return $result; + } +} diff --git a/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/BotParserAbstract.php b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/BotParserAbstract.php new file mode 100644 index 000000000..c5dacc189 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/BotParserAbstract.php @@ -0,0 +1,23 @@ + '2345 Browser', + '36' => '360 Phone Browser', + '3B' => '360 Browser', + 'AA' => 'Avant Browser', + 'AB' => 'ABrowse', + 'AF' => 'ANT Fresco', + 'AG' => 'ANTGalio', + 'AL' => 'Aloha Browser', + 'AH' => 'Aloha Browser Lite', + 'AM' => 'Amaya', + 'AO' => 'Amigo', + 'AN' => 'Android Browser', + 'AD' => 'AOL Shield', + 'AR' => 'Arora', + 'AV' => 'Amiga Voyager', + 'AW' => 'Amiga Aweb', + 'AT' => 'Atomic Web Browser', + 'AS' => 'Avast Secure Browser', + 'VG' => 'AVG Secure Browser', + 'BA' => 'Beaker Browser', + 'BM' => 'Beamrise', + 'BB' => 'BlackBerry Browser', + 'BD' => 'Baidu Browser', + 'BS' => 'Baidu Spark', + 'BI' => 'Basilisk', + 'BE' => 'Beonex', + 'BH' => 'BlackHawk', + 'BJ' => 'Bunjalloo', + 'BL' => 'B-Line', + 'BR' => 'Brave', + 'BK' => 'BriskBard', + 'BX' => 'BrowseX', + 'CA' => 'Camino', + 'CL' => 'CCleaner', + 'CC' => 'Coc Coc', + 'CD' => 'Comodo Dragon', + 'C1' => 'Coast', + 'CX' => 'Charon', + 'CE' => 'CM Browser', + 'CF' => 'Chrome Frame', + 'HC' => 'Headless Chrome', + 'CH' => 'Chrome', + 'CI' => 'Chrome Mobile iOS', + 'CK' => 'Conkeror', + 'CM' => 'Chrome Mobile', + 'CN' => 'CoolNovo', + 'CO' => 'CometBird', + 'CB' => 'COS Browser', + 'CP' => 'ChromePlus', + 'CR' => 'Chromium', + 'CY' => 'Cyberfox', + 'CS' => 'Cheshire', + 'CT' => 'Crusta', + 'CU' => 'Cunaguaro', + 'CV' => 'Chrome Webview', + 'DB' => 'dbrowser', + 'DE' => 'Deepnet Explorer', + 'DT' => 'Delta Browser', + 'DF' => 'Dolphin', + 'DO' => 'Dorado', + 'DL' => 'Dooble', + 'DI' => 'Dillo', + 'DD' => 'DuckDuckGo Privacy Browser', + 'EC' => 'Ecosia', + 'EI' => 'Epic', + 'EL' => 'Elinks', + 'EB' => 'Element Browser', + 'EZ' => 'eZ Browser', + 'EU' => 'EUI Browser', + 'EP' => 'GNOME Web', + 'ES' => 'Espial TV Browser', + 'FA' => 'Falkon', + 'FX' => 'Faux Browser', + 'F1' => 'Firefox Mobile iOS', + 'FB' => 'Firebird', + 'FD' => 'Fluid', + 'FE' => 'Fennec', + 'FF' => 'Firefox', + 'FK' => 'Firefox Focus', + 'FY' => 'Firefox Reality', + 'FR' => 'Firefox Rocket', + 'FL' => 'Flock', + 'FM' => 'Firefox Mobile', + 'FW' => 'Fireweb', + 'FN' => 'Fireweb Navigator', + 'FU' => 'FreeU', + 'GA' => 'Galeon', + 'GE' => 'Google Earth', + 'HA' => 'Hawk Turbo Browser', + 'HO' => 'hola! Browser', + 'HJ' => 'HotJava', + 'HU' => 'Huawei Browser', + 'IB' => 'IBrowse', + 'IC' => 'iCab', + 'I2' => 'iCab Mobile', + 'I1' => 'Iridium', + 'I3' => 'Iron Mobile', + 'I4' => 'IceCat', + 'ID' => 'IceDragon', + 'IV' => 'Isivioo', + 'IW' => 'Iceweasel', + 'IE' => 'Internet Explorer', + 'IM' => 'IE Mobile', + 'IR' => 'Iron', + 'JS' => 'Jasmine', + 'JI' => 'Jig Browser', + 'JO' => 'Jio Browser', + 'KB' => 'K.Browser', + 'KI' => 'Kindle Browser', + 'KM' => 'K-meleon', + 'KO' => 'Konqueror', + 'KP' => 'Kapiko', + 'KN' => 'Kinza', + 'KW' => 'Kiwi', + 'KY' => 'Kylo', + 'KZ' => 'Kazehakase', + 'LB' => 'Cheetah Browser', + 'LF' => 'LieBaoFast', + 'LG' => 'LG Browser', + 'LI' => 'Links', + 'LO' => 'Lovense Browser', + 'LU' => 'LuaKit', + 'LS' => 'Lunascape', + 'LX' => 'Lynx', + 'M1' => 'mCent', + 'MB' => 'MicroB', + 'MC' => 'NCSA Mosaic', + 'MZ' => 'Meizu Browser', + 'ME' => 'Mercury', + 'MF' => 'Mobile Safari', + 'MI' => 'Midori', + 'MO' => 'Mobicip', + 'MU' => 'MIUI Browser', + 'MS' => 'Mobile Silk', + 'MN' => 'Minimo', + 'MT' => 'Mint Browser', + 'MX' => 'Maxthon', + 'NB' => 'Nokia Browser', + 'NO' => 'Nokia OSS Browser', + 'NV' => 'Nokia Ovi Browser', + 'NX' => 'Nox Browser', + 'NE' => 'NetSurf', + 'NF' => 'NetFront', + 'NL' => 'NetFront Life', + 'NP' => 'NetPositive', + 'NS' => 'Netscape', + 'NT' => 'NTENT Browser', + 'OC' => 'Oculus Browser', + 'O1' => 'Opera Mini iOS', + 'OB' => 'Obigo', + 'OD' => 'Odyssey Web Browser', + 'OF' => 'Off By One', + 'OE' => 'ONE Browser', + 'OX' => 'Opera GX', + 'OG' => 'Opera Neon', + 'OH' => 'Opera Devices', + 'OI' => 'Opera Mini', + 'OM' => 'Opera Mobile', + 'OP' => 'Opera', + 'ON' => 'Opera Next', + 'OO' => 'Opera Touch', + 'OS' => 'Ordissimo', + 'OR' => 'Oregano', + 'OY' => 'Origyn Web Browser', + 'OV' => 'Openwave Mobile Browser', + 'OW' => 'OmniWeb', + 'OT' => 'Otter Browser', + 'PL' => 'Palm Blazer', + 'PM' => 'Pale Moon', + 'PP' => 'Oppo Browser', + 'PR' => 'Palm Pre', + 'PU' => 'Puffin', + 'PW' => 'Palm WebPro', + 'PA' => 'Palmscape', + 'PX' => 'Phoenix', + 'PO' => 'Polaris', + 'PT' => 'Polarity', + 'PS' => 'Microsoft Edge', + 'Q1' => 'QQ Browser Mini', + 'QQ' => 'QQ Browser', + 'QT' => 'Qutebrowser', + 'QZ' => 'QupZilla', + 'QM' => 'Qwant Mobile', + 'QW' => 'QtWebEngine', + 'RE' => 'Realme Browser', + 'RK' => 'Rekonq', + 'RM' => 'RockMelt', + 'SB' => 'Samsung Browser', + 'SA' => 'Sailfish Browser', + 'SC' => 'SEMC-Browser', + 'SE' => 'Sogou Explorer', + 'SF' => 'Safari', + 'SW' => 'SalamWeb', + 'SH' => 'Shiira', + 'S1' => 'SimpleBrowser', + 'SK' => 'Skyfire', + 'SS' => 'Seraphic Sraf', + 'SL' => 'Sleipnir', + 'SN' => 'Snowshoe', + 'SO' => 'Sogou Mobile Browser', + 'S2' => 'Splash', + 'SI' => 'Sputnik Browser', + 'SR' => 'Sunrise', + 'SP' => 'SuperBird', + 'SU' => 'Super Fast Browser', + 'S0' => 'START Internet Browser', + 'ST' => 'Streamy', + 'SX' => 'Swiftfox', + 'SZ' => 'Seznam Browser', + 'TO' => 't-online.de Browser', + 'TA' => 'Tao Browser', + 'TF' => 'TenFourFox', + 'TB' => 'Tenta Browser', + 'TZ' => 'Tizen Browser', + 'TS' => 'TweakStyle', + 'TV' => 'TV Bro', + 'UB' => 'UBrowser', + 'UC' => 'UC Browser', + 'UM' => 'UC Browser Mini', + 'UT' => 'UC Browser Turbo', + 'UZ' => 'Uzbl', + 'VI' => 'Vivaldi', + 'VV' => 'vivo Browser', + 'VB' => 'Vision Mobile Browser', + 'WI' => 'Wear Internet Browser', + 'WP' => 'Web Explorer', + 'WE' => 'WebPositive', + 'WF' => 'Waterfox', + 'WH' => 'Whale Browser', + 'WO' => 'wOSBrowser', + 'WT' => 'WeTab Browser', + 'YA' => 'Yandex Browser', + 'YL' => 'Yandex Browser Lite', + 'XI' => 'Xiino' + + // detected browsers in older versions + // 'IA' => 'Iceape', => pim + // 'SM' => 'SeaMonkey', => pim + ); + + /** + * Browser families mapped to the short codes of the associated browsers + * + * @var array + */ + protected static $browserFamilies = array( + 'Android Browser' => array('AN', 'MU'), + 'BlackBerry Browser' => array('BB'), + 'Baidu' => array('BD', 'BS'), + 'Amiga' => array('AV', 'AW'), + 'Chrome' => array('CH', 'BA', 'BR', 'CC', 'CD', 'CM', 'CI', 'CF', 'CN', 'CR', 'CP', 'DD', 'IR', 'RM', 'AO', 'TS', 'VI', 'PT', 'AS', 'TB', 'AD', 'SB', 'WP', 'I3', 'CV', 'WH', 'SZ', 'QW', 'LF', 'KW', '2B', 'CE', 'EC', 'MT', 'MS', 'HA', 'OC', 'MZ', 'BM', 'KN', 'SW', 'M1', 'FA', 'TA', 'AH', 'CL', 'SU', 'EU', 'UB', 'LO', 'VG', 'TV'), + 'Firefox' => array('FF', 'FE', 'FM', 'SX', 'FB', 'PX', 'MB', 'EI', 'WF', 'CU', 'TF', 'QM', 'FR', 'I4', 'GZ', 'MO', 'F1', 'BI', 'MN', 'BH', 'TO', 'OS', 'FY'), + 'Internet Explorer' => array('IE', 'IM', 'PS'), + 'Konqueror' => array('KO'), + 'NetFront' => array('NF'), + 'NetSurf' => array('NE'), + 'Nokia Browser' => array('NB', 'NO', 'NV', 'DO'), + 'Opera' => array('OP', 'OM', 'OI', 'ON', 'OO', 'OG', 'OH', 'O1', 'OX'), + 'Safari' => array('SF', 'MF', 'SO'), + 'Sailfish Browser' => array('SA') + ); + + /** + * Browsers that are available for mobile devices only + * + * @var array + */ + protected static $mobileOnlyBrowsers = array( + '36', 'OC', 'PU', 'SK', 'MF', 'OI', 'OM', 'DD', 'DB', 'ST', 'BL', 'IV', 'FM', 'C1', 'AL', 'SA', 'SB', 'FR', 'WP', 'HA', 'NX', 'HU', 'VV', 'RE', 'CB', 'MZ', 'UM', 'FK', 'FX', 'WI', 'MN', 'M1', 'AH', 'SU', 'EU', 'EZ', 'UT', 'DT', 'S0' + ); + + /** + * Returns list of all available browsers + * @return array + */ + public static function getAvailableBrowsers() + { + return self::$availableBrowsers; + } + + /** + * Returns list of all available browser families + * @return array + */ + public static function getAvailableBrowserFamilies() + { + return self::$browserFamilies; + } + + + /** + * @param string $browserLabel + * @return bool|string If false, "Unknown" + */ + public static function getBrowserFamily($browserLabel) + { + foreach (self::$browserFamilies as $browserFamily => $browserLabels) { + if (in_array($browserLabel, $browserLabels)) { + return $browserFamily; + } + } + return false; + } + + /** + * Returns if the given browser is mobile only + * + * @param string $browser Label or name of browser + * @return bool + */ + public static function isMobileOnlyBrowser($browser) + { + return in_array($browser, self::$mobileOnlyBrowsers) || (in_array($browser, self::$availableBrowsers) && in_array(array_search($browser, self::$availableBrowsers), self::$mobileOnlyBrowsers)); + } + + public function parse() + { + foreach ($this->getRegexes() as $regex) { + $matches = $this->matchUserAgent($regex['regex']); + if ($matches) { + break; + } + } + + if (empty($matches)) { + return null; + } + + $name = $this->buildByMatch($regex['name'], $matches); + + foreach (self::getAvailableBrowsers() as $browserShort => $browserName) { + if (strtolower($name) == strtolower($browserName)) { + $version = (string) $this->buildVersion($regex['version'], $matches); + $engine = $this->buildEngine(isset($regex['engine']) ? $regex['engine'] : array(), $version); + $engineVersion = $this->buildEngineVersion($engine); + return array( + 'type' => 'browser', + 'name' => $browserName, + 'short_name' => $browserShort, + 'version' => $version, + 'engine' => $engine, + 'engine_version' => $engineVersion, + ); + } + } + + // This Exception should never be thrown. If so a defined browser name is missing in $availableBrowsers + throw new \Exception(sprintf('Detected browser name "%s" was not found in $availableBrowsers. Tried to parse user agent: %s', $name, $this->userAgent)); // @codeCoverageIgnore + } + + protected function buildEngine($engineData, $browserVersion) + { + $engine = ''; + // if an engine is set as default + if (isset($engineData['default'])) { + $engine = $engineData['default']; + } + // check if engine is set for browser version + if (array_key_exists('versions', $engineData) && is_array($engineData['versions'])) { + foreach ($engineData['versions'] as $version => $versionEngine) { + if (version_compare($browserVersion, $version) >= 0) { + $engine = $versionEngine; + } + } + } + // try to detect the engine using the regexes + if (empty($engine)) { + $engineParser = new Engine(); + $engineParser->setYamlParser($this->getYamlParser()); + $engineParser->setCache($this->getCache()); + $engineParser->setUserAgent($this->userAgent); + $engine = $engineParser->parse(); + } + + return $engine; + } + + protected function buildEngineVersion($engine) + { + $engineVersionParser = new Engine\Version($this->userAgent, $engine); + + return $engineVersionParser->parse(); + } +} diff --git a/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Client/Browser/Engine.php b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Client/Browser/Engine.php new file mode 100644 index 000000000..ddc05dcb8 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Client/Browser/Engine.php @@ -0,0 +1,79 @@ +getRegexes() as $regex) { + $matches = $this->matchUserAgent($regex['regex']); + if ($matches) { + break; + } + } + + if (!$matches) { + return ''; + } + + $name = $this->buildByMatch($regex['name'], $matches); + + foreach (self::getAvailableEngines() as $engineName) { + if (strtolower($name) == strtolower($engineName)) { + return $engineName; + } + } + + // This Exception should never be thrown. If so a defined browser name is missing in $availableEngines + throw new \Exception('Detected browser engine was not found in $availableEngines. Tried to parse user agent: '.$this->userAgent); // @codeCoverageIgnore + } +} diff --git a/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Client/Browser/Engine/Version.php b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Client/Browser/Engine/Version.php new file mode 100644 index 000000000..e246c7bd3 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Client/Browser/Engine/Version.php @@ -0,0 +1,54 @@ +engine = $engine; + } + + public function parse() + { + if (empty($this->engine)) { + return ''; + } + + preg_match("~$this->engine\s*/?\s*((?(?=\d+\.\d)\d+[.\d]*|\d{1,7}(?=(?:\D|$))))~i", $this->userAgent, $matches); + + if (!$matches) { + return ''; + } + + return array_pop($matches); + } +} diff --git a/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Client/ClientParserAbstract.php b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Client/ClientParserAbstract.php new file mode 100644 index 000000000..1c63af230 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Client/ClientParserAbstract.php @@ -0,0 +1,74 @@ + If no matches found: return + * -> Otherwise: + * Step 2: Walk through the list of regexes in feed_readers.yml and try to match every one + * -> Return the matched feed reader + * + * NOTE: Doing the big match before matching every single regex speeds up the detection + */ + public function parse() + { + $result = null; + + if ($this->preMatchOverall()) { + foreach ($this->getRegexes() as $regex) { + $matches = $this->matchUserAgent($regex['regex']); + + if ($matches) { + $result = array( + 'type' => $this->parserName, + 'name' => $this->buildByMatch($regex['name'], $matches), + 'version' => $this->buildVersion($regex['version'], $matches) + ); + break; + } + } + } + + return $result; + } + + /** + * Returns all names defined in the regexes + * + * Attention: This method might not return all names of detected clients + * + * @return array + */ + public static function getAvailableClients() + { + $instance = new static(); + $regexes = $instance->getRegexes(); + $names = array(); + foreach ($regexes as $regex) { + if ($regex['name'] != '$1') { + $names[] = $regex['name']; + } + } + + natcasesort($names); + + return array_unique($names); + } +} diff --git a/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Client/FeedReader.php b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Client/FeedReader.php new file mode 100644 index 000000000..edc189e76 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Client/FeedReader.php @@ -0,0 +1,21 @@ +preMatchOverall()) { + return false; + } + + return parent::parse(); + } +} diff --git a/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Device/CarBrowser.php b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Device/CarBrowser.php new file mode 100644 index 000000000..46b9040fc --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Device/CarBrowser.php @@ -0,0 +1,30 @@ +preMatchOverall()) { + return false; + } + + return parent::parse(); + } +} diff --git a/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Device/Console.php b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Device/Console.php new file mode 100644 index 000000000..30da47e50 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Device/Console.php @@ -0,0 +1,30 @@ +preMatchOverall()) { + return false; + } + + return parent::parse(); + } +} diff --git a/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Device/DeviceParserAbstract.php b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Device/DeviceParserAbstract.php new file mode 100644 index 000000000..57ef166f5 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Device/DeviceParserAbstract.php @@ -0,0 +1,832 @@ + self::DEVICE_TYPE_DESKTOP, + 'smartphone' => self::DEVICE_TYPE_SMARTPHONE, + 'tablet' => self::DEVICE_TYPE_TABLET, + 'feature phone' => self::DEVICE_TYPE_FEATURE_PHONE, + 'console' => self::DEVICE_TYPE_CONSOLE, + 'tv' => self::DEVICE_TYPE_TV, + 'car browser' => self::DEVICE_TYPE_CAR_BROWSER, + 'smart display' => self::DEVICE_TYPE_SMART_DISPLAY, + 'camera' => self::DEVICE_TYPE_CAMERA, + 'portable media player' => self::DEVICE_TYPE_PORTABLE_MEDIA_PAYER, + 'phablet' => self::DEVICE_TYPE_PHABLET, + 'smart speaker' => self::DEVICE_TYPE_SMART_SPEAKER, + ); + + /** + * Known device brands + * + * Note: Before using a new brand in on of the regex files, it needs to be added here + * + * @var array + */ + public static $deviceBrands = array( + '3Q' => '3Q', + '4G' => '4Good', + 'AE' => 'Ace', + 'AA' => 'AllCall', + 'AC' => 'Acer', + 'A9' => 'Advan', + 'AD' => 'Advance', + 'A3' => 'AGM', + 'AZ' => 'Ainol', + 'AI' => 'Airness', + '0A' => 'AIS', + 'AW' => 'Aiwa', + 'AK' => 'Akai', + '1A' => 'Alba', + 'AL' => 'Alcatel', + '4A' => 'Aligator', + '3A' => 'AllDocube', + 'A2' => 'Allview', + 'A7' => 'Allwinner', + 'A1' => 'Altech UEC', + 'A5' => 'altron', + 'AN' => 'Arnova', + '2A' => 'Atom', + 'KN' => 'Amazon', + 'AG' => 'AMGOO', + 'AO' => 'Amoi', + 'AP' => 'Apple', + 'AR' => 'Archos', + 'AS' => 'ARRIS', + 'AB' => 'Arian Space', + 'AT' => 'Airties', + 'A6' => 'Ark', + 'A4' => 'Ask', + 'A8' => 'Assistant', + 'A0' => 'ANS', + 'AU' => 'Asus', + 'AH' => 'AVH', + 'AV' => 'Avvio', + 'AX' => 'Audiovox', + 'AY' => 'Axxion', + 'AM' => 'Azumi Mobile', + 'BB' => 'BBK', + 'BE' => 'Becker', + 'B5' => 'Beeline', + 'BI' => 'Bird', + 'BT' => 'Bitel', + 'BG' => 'BGH', + 'BL' => 'Beetel', + 'BP' => 'Blaupunkt', + 'B3' => 'Bluboo', + 'BF' => 'Black Fox', + 'B6' => 'BDF', + 'BM' => 'Bmobile', + 'BN' => 'Barnes & Noble', + 'BO' => 'BangOlufsen', + 'BQ' => 'BenQ', + 'BS' => 'BenQ-Siemens', + 'BU' => 'Blu', + 'BD' => 'Bluegood', + 'B2' => 'Blackview', + 'B4' => 'bogo', + 'BW' => 'Boway', + 'BZ' => 'Bezkam', + 'BX' => 'bq', + 'BV' => 'Bravis', + 'BR' => 'Brondi', + 'B1' => 'Bush', + 'CB' => 'CUBOT', + 'CF' => 'Carrefour', + 'CP' => 'Captiva', + 'CS' => 'Casio', + 'R4' => 'Casper', + 'CA' => 'Cat', + 'C9' => 'CAGI', + 'CE' => 'Celkon', + 'CC' => 'ConCorde', + 'C2' => 'Changhong', + '2C' => 'Ghong', + 'CH' => 'Cherry Mobile', + '1C' => 'Chuwi', + 'L8' => 'Clarmin', + 'CK' => 'Cricket', + 'C1' => 'Crosscall', + 'CL' => 'Compal', + 'CN' => 'CnM', + 'CM' => 'Crius Mea', + 'C3' => 'China Mobile', + 'CR' => 'CreNova', + 'CT' => 'Capitel', + 'CQ' => 'Compaq', + 'CO' => 'Coolpad', + 'C5' => 'Condor', + 'CW' => 'Cowon', + 'CU' => 'Cube', + 'CY' => 'Coby Kyros', + 'C6' => 'Comio', + 'C7' => 'ComTrade Tesla', + 'C8' => 'Concord', + 'CX' => 'Crescent', + 'C4' => 'Cyrus', + 'CV' => 'CVTE', + 'D5' => 'Daewoo', + 'DA' => 'Danew', + 'DT' => 'Datang', + 'D1' => 'Datsun', + 'DE' => 'Denver', + 'DW' => 'DeWalt', + 'DX' => 'DEXP', + 'DS' => 'Desay', + 'DB' => 'Dbtel', + 'DC' => 'DoCoMo', + 'DG' => 'Dialog', + 'DI' => 'Dicam', + 'D4' => 'Digi', + 'D3' => 'Digicel', + 'DD' => 'Digiland', + 'D2' => 'Digma', + 'D6' => 'Divisat', + 'DL' => 'Dell', + 'DN' => 'DNS', + 'DM' => 'DMM', + 'DO' => 'Doogee', + 'DV' => 'Doov', + 'DP' => 'Dopod', + 'DR' => 'Doro', + 'DU' => 'Dune HD', + 'EB' => 'E-Boda', + 'EA' => 'EBEST', + 'EC' => 'Ericsson', + 'E7' => 'Ergo', + 'ED' => 'Energizer', + 'E4' => 'Echo Mobiles', + 'ES' => 'ECS', + 'E6' => 'EE', + 'EI' => 'Ezio', + 'EM' => 'Eks Mobility', + 'EL' => 'Elephone', + 'EG' => 'Elenberg', + 'EP' => 'Easypix', + 'EK' => 'EKO', + 'E1' => 'Energy Sistem', + 'ER' => 'Ericy', + 'EE' => 'Essential', + 'EN' => 'Eton', + 'E2' => 'Essentielb', + '1E' => 'Etuline', + 'ET' => 'eTouch', + 'EV' => 'Evertek', + 'E3' => 'Evolio', + 'EO' => 'Evolveo', + 'EX' => 'Explay', + 'E0' => 'EvroMedia', + 'E5' => 'Extrem', + 'EZ' => 'Ezze', + 'E8' => 'E-tel', + 'E9' => 'Evercoss', + 'EU' => 'Eurostar', + 'FA' => 'Fairphone', + 'FM' => 'Famoco', + 'FE' => 'Fengxiang', + 'FI' => 'FiGO', + 'FL' => 'Fly', + 'F1' => 'FinePower', + 'FT' => 'Freetel', + 'FR' => 'Forstar', + 'FO' => 'Foxconn', + 'F2' => 'FORME', + 'FN' => 'FNB', + 'FU' => 'Fujitsu', + 'FD' => 'Fondi', + 'GT' => 'G-TiDE', + 'GM' => 'Garmin-Asus', + 'GA' => 'Gateway', + 'GD' => 'Gemini', + 'GN' => 'General Mobile', + 'GE' => 'Geotel', + 'GH' => 'Ghia', + 'GI' => 'Gionee', + 'GG' => 'Gigabyte', + 'GS' => 'Gigaset', + 'GZ' => 'Ginzzu', + 'G4' => 'Globex', + 'GC' => 'GOCLEVER', + 'GL' => 'Goly', + 'GO' => 'Google', + 'G1' => 'GoMobile', + 'GR' => 'Gradiente', + 'GP' => 'Grape', + 'GU' => 'Grundig', + 'HF' => 'Hafury', + 'HA' => 'Haier', + 'HS' => 'Hasee', + 'HE' => 'HannSpree', + 'HI' => 'Hisense', + 'HL' => 'Hi-Level', + 'H2' => 'Highscreen', + 'H1' => 'Hoffmann', + 'HM' => 'Homtom', + 'HO' => 'Hosin', + 'HZ' => 'Hoozo', + 'HP' => 'HP', + 'HT' => 'HTC', + 'HU' => 'Huawei', + 'HX' => 'Humax', + 'HY' => 'Hyrican', + 'HN' => 'Hyundai', + 'IA' => 'Ikea', + 'IB' => 'iBall', + 'IJ' => 'i-Joy', + 'IY' => 'iBerry', + 'IH' => 'iHunt', + 'IK' => 'iKoMo', + 'IE' => 'iView', + 'IM' => 'i-mate', + 'I1' => 'iOcean', + 'I2' => 'IconBIT', + 'IL' => 'IMO Mobile', + 'I7' => 'iLA', + 'IW' => 'iNew', + 'IP' => 'iPro', + 'IF' => 'Infinix', + 'I0' => 'InFocus', + 'I5' => 'InnJoo', + 'IN' => 'Innostream', + 'IS' => 'Insignia', + 'I4' => 'Inoi', + 'IR' => 'iRola', + 'IU' => 'iRulu', + 'I6' => 'Irbis', + 'II' => 'Inkti', + 'IX' => 'Intex', + 'IO' => 'i-mobile', + 'IQ' => 'INQ', + 'IT' => 'Intek', + 'IV' => 'Inverto', + 'I3' => 'Impression', + 'IZ' => 'iTel', + 'I9' => 'iZotron', + 'JA' => 'JAY-Tech', + 'JI' => 'Jiayu', + 'JO' => 'Jolla', + 'J5' => 'Just5', + 'KL' => 'Kalley', + 'K4' => 'Kaan', + 'K7' => 'Kaiomy', + 'K6' => 'Kanji', + 'KA' => 'Karbonn', + 'K5' => 'KATV1', + 'KD' => 'KDDI', + 'K1' => 'Kiano', + 'KV' => 'Kivi', + 'KI' => 'Kingsun', + 'KC' => 'Kocaso', + 'KG' => 'Kogan', + 'KO' => 'Konka', + 'KM' => 'Komu', + 'KB' => 'Koobee', + 'KT' => 'K-Touch', + 'KH' => 'KT-Tech', + 'KK' => 'Kodak', + 'KP' => 'KOPO', + 'KW' => 'Konrow', + 'KR' => 'Koridy', + 'K2' => 'KRONO', + 'KS' => 'Kempler & Strauss', + 'K3' => 'Keneksi', + 'KU' => 'Kumai', + 'KY' => 'Kyocera', + 'KZ' => 'Kazam', + 'KE' => 'Krüger&Matz', + 'LQ' => 'LAIQ', + 'L2' => 'Landvo', + 'L6' => 'Land Rover', + 'LV' => 'Lava', + 'LA' => 'Lanix', + 'LK' => 'Lark', + 'LC' => 'LCT', + 'L5' => 'Leagoo', + 'LD' => 'Ledstar', + 'L1' => 'LeEco', + 'L4' => 'Lemhoov', + 'LE' => 'Lenovo', + 'LN' => 'Lenco', + 'LT' => 'Leotec', + 'L7' => 'Lephone', + 'LP' => 'Le Pan', + 'LG' => 'LG', + 'LI' => 'Lingwin', + 'LO' => 'Loewe', + 'LM' => 'Logicom', + 'L3' => 'Lexand', + 'LX' => 'Lexibook', + 'LY' => 'LYF', + 'LU' => 'Lumus', + 'L9' => 'Luna', + 'MN' => 'M4tel', + 'MJ' => 'Majestic', + 'MA' => 'Manta Multimedia', + '5M' => 'Mann', + '2M' => 'Masstel', + 'MW' => 'Maxwest', + '7M' => 'Maxcom', + 'M0' => 'Maze', + 'MB' => 'Mobistel', + '0M' => 'Mecool', + 'M3' => 'Mecer', + 'MD' => 'Medion', + 'M2' => 'MEEG', + 'M1' => 'Meizu', + '3M' => 'Meitu', + 'ME' => 'Metz', + 'MX' => 'MEU', + 'MI' => 'MicroMax', + 'M5' => 'MIXC', + 'MH' => 'Mobiola', + '4M' => 'Mobicel', + 'M6' => 'Mobiistar', + 'MC' => 'Mediacom', + 'MK' => 'MediaTek', + 'MO' => 'Mio', + 'M7' => 'Miray', + 'MM' => 'Mpman', + 'M4' => 'Modecom', + 'MF' => 'Mofut', + 'MR' => 'Motorola', + 'MV' => 'Movic', + 'MS' => 'Microsoft', + 'M9' => 'MTC', + 'MP' => 'MegaFon', + 'MZ' => 'MSI', + 'MU' => 'Memup', + 'MT' => 'Mitsubishi', + 'ML' => 'MLLED', + 'MQ' => 'M.T.T.', + 'N4' => 'MTN', + 'MY' => 'MyPhone', + '1M' => 'MYFON', + 'MG' => 'MyWigo', + 'M8' => 'Myria', + '6M' => 'Mystery', + 'N3' => 'Navon', + 'N7' => 'National', + 'N5' => 'NOA', + 'NE' => 'NEC', + 'NF' => 'Neffos', + 'NA' => 'Netgear', + 'NU' => 'NeuImage', + 'NG' => 'NGM', + 'NZ' => 'NG Optics', + 'N6' => 'Nobby', + 'NO' => 'Nous', + 'NI' => 'Nintendo', + 'N1' => 'Noain', + 'N2' => 'Nextbit', + 'NK' => 'Nokia', + 'NV' => 'Nvidia', + 'NB' => 'Noblex', + 'NM' => 'Nomi', + 'N0' => 'Nuvo', + 'NL' => 'NUU Mobile', + 'NY' => 'NYX Mobile', + 'NN' => 'Nikon', + 'NW' => 'Newgen', + 'NS' => 'NewsMy', + 'NX' => 'Nexian', + 'NT' => 'NextBook', + 'O3' => 'O+', + 'OB' => 'Obi', + 'O1' => 'Odys', + 'OD' => 'Onda', + 'ON' => 'OnePlus', + 'OP' => 'OPPO', + 'OR' => 'Orange', + 'OS' => 'Ordissimo', + 'OT' => 'O2', + 'OK' => 'Ouki', + 'OE' => 'Oukitel', + 'OU' => 'OUYA', + 'OO' => 'Opsson', + 'OV' => 'Overmax', + 'OY' => 'Oysters', + 'OW' => 'öwn', + 'PN' => 'Panacom', + 'PA' => 'Panasonic', + 'PB' => 'PCBOX', + 'PC' => 'PCD', + 'PD' => 'PCD Argentina', + 'PE' => 'PEAQ', + 'PG' => 'Pentagram', + 'PH' => 'Philips', + 'PI' => 'Pioneer', + 'PX' => 'Pixus', + 'PL' => 'Polaroid', + 'P5' => 'Polytron', + 'P9' => 'Primepad', + 'P6' => 'Proline', + 'PM' => 'Palm', + 'PO' => 'phoneOne', + 'PT' => 'Pantech', + 'PY' => 'Ployer', + 'P4' => 'Plum', + 'PV' => 'Point of View', + 'PP' => 'PolyPad', + 'P2' => 'Pomp', + 'P3' => 'PPTV', + 'PS' => 'Positivo', + 'PR' => 'Prestigio', + 'P1' => 'ProScan', + 'PU' => 'PULID', + 'QI' => 'Qilive', + 'QT' => 'Qtek', + 'QH' => 'Q-Touch', + 'QM' => 'QMobile', + 'QA' => 'Quantum', + 'QU' => 'Quechua', + 'QO' => 'Qumo', + 'RA' => 'Ramos', + 'RC' => 'RCA Tablets', + 'RB' => 'Readboy', + 'RI' => 'Rikomagic', + 'RN' => 'Rinno', + 'RV' => 'Riviera', + 'RM' => 'RIM', + 'RK' => 'Roku', + 'RO' => 'Rover', + 'R6' => 'RoverPad', + 'RR' => 'Roadrover', + 'R1' => 'Rokit', + 'R3' => 'Rombica', + 'RT' => 'RT Project', + 'RX' => 'Ritmix', + 'R7' => 'Ritzviva', + 'R5' => 'Ross&Moor', + 'R2' => 'R-TV', + 'RG' => 'RugGear', + 'RU' => 'Runbo', + 'SQ' => 'Santin', + 'SA' => 'Samsung', + 'S0' => 'Sanei', + 'SD' => 'Sega', + 'SL' => 'Selfix', + 'SE' => 'Sony Ericsson', + 'S1' => 'Sencor', + 'SF' => 'Softbank', + 'SX' => 'SFR', + 'SG' => 'Sagem', + 'SH' => 'Sharp', + '7S' => 'Shift Phones', + '3S' => 'Shuttle', + 'SI' => 'Siemens', + 'SJ' => 'Silent Circle', + '1S' => 'Sigma', + 'SN' => 'Sendo', + 'S6' => 'Senseit', + 'EW' => 'Senwa', + 'SW' => 'Sky', + 'SK' => 'Skyworth', + 'SC' => 'Smartfren', + 'SO' => 'Sony', + 'OI' => 'Sonim', + 'SP' => 'Spice', + '6S' => 'Spectrum', + '5S' => 'Sunvell', + 'SU' => 'SuperSonic', + 'S5' => 'Supra', + 'SV' => 'Selevision', + 'SY' => 'Sanyo', + 'SM' => 'Symphony', + '4S' => 'Syrox', + 'SR' => 'Smart', + 'S7' => 'Smartisan', + 'S4' => 'Star', + 'SB' => 'STF Mobile', + 'S8' => 'STK', + 'S9' => 'Savio', + '2S' => 'Starway', + 'ST' => 'Storex', + 'S2' => 'Stonex', + 'S3' => 'SunVan', + 'SZ' => 'Sumvision', + 'SS' => 'SWISSMOBILITY', + '10' => 'Simbans', + 'X1' => 'Safaricom', + 'TA' => 'Tesla', + 'T5' => 'TB Touch', + 'TC' => 'TCL', + 'T7' => 'Teclast', + 'TE' => 'Telit', + 'T4' => 'ThL', + 'TH' => 'TiPhone', + 'TB' => 'Tecno Mobile', + 'TP' => 'TechPad', + 'TD' => 'Tesco', + 'TI' => 'TIANYU', + 'TG' => 'Telego', + 'TL' => 'Telefunken', + 'T2' => 'Telenor', + 'TM' => 'T-Mobile', + 'TN' => 'Thomson', + 'TQ' => 'Timovi', + 'TY' => 'Tooky', + 'T1' => 'Tolino', + 'T9' => 'Top House', + 'TO' => 'Toplux', + 'T8' => 'Touchmate', + 'TS' => 'Toshiba', + 'TT' => 'TechnoTrend', + 'T6' => 'TrekStor', + 'T3' => 'Trevi', + 'TU' => 'Tunisie Telecom', + 'TR' => 'Turbo-X', + '1T' => 'Turbo', + '11' => 'True', + 'TV' => 'TVC', + 'TX' => 'TechniSat', + 'TZ' => 'teXet', + 'UC' => 'U.S. Cellular', + 'UH' => 'Uhappy', + 'UG' => 'Ugoos', + 'UL' => 'Ulefone', + 'UO' => 'Unnecto', + 'UN' => 'Unowhy', + 'US' => 'Uniscope', + 'UX' => 'Unimax', + 'UM' => 'UMIDIGI', + 'UU' => 'Unonu', + 'UK' => 'UTOK', + 'UA' => 'Umax', + 'UT' => 'UTStarcom', + 'UZ' => 'Unihertz', + 'VA' => 'Vastking', + 'VD' => 'Videocon', + 'VE' => 'Vertu', + 'VN' => 'Venso', + 'V5' => 'Vivax', + 'VI' => 'Vitelcom', + 'V7' => 'Vinga', + 'VK' => 'VK Mobile', + 'VS' => 'ViewSonic', + 'V9' => 'Vsun', + 'V8' => 'Vesta', + 'VT' => 'Vestel', + 'VR' => 'Vernee', + 'V4' => 'Verizon', + 'VL' => 'Verykool', + 'V6' => 'VGO TEL', + 'VV' => 'Vivo', + 'VX' => 'Vertex', + 'V3' => 'Vinsoc', + 'V2' => 'Vonino', + 'VG' => 'Vorago', + 'V1' => 'Voto', + 'VO' => 'Voxtel', + 'VF' => 'Vodafone', + 'VZ' => 'Vizio', + 'VW' => 'Videoweb', + 'VU' => 'Vulcan', + 'WA' => 'Walton', + 'WF' => 'Wileyfox', + 'WN' => 'Wink', + 'WM' => 'Weimei', + 'WE' => 'WellcoM', + 'WY' => 'Wexler', + 'WI' => 'Wiko', + 'WP' => 'Wieppo', + 'WL' => 'Wolder', + 'WG' => 'Wolfgang', + 'WO' => 'Wonu', + 'W1' => 'Woo', + 'WX' => 'Woxter', + 'XV' => 'X-View', + 'XI' => 'Xiaomi', + 'XL' => 'Xiaolajiao', + 'XN' => 'Xion', + 'XO' => 'Xolo', + 'XR' => 'Xoro', + 'YA' => 'Yarvik', + 'YD' => 'Yandex', + 'Y2' => 'Yes', + 'YE' => 'Yezz', + 'Y1' => 'Yu', + 'YU' => 'Yuandao', + 'YS' => 'Yusun', + 'YO' => 'Yota', + 'YT' => 'Ytone', + 'YX' => 'Yxtel', + 'ZE' => 'Zeemi', + 'ZK' => 'Zenek', + 'ZO' => 'Zonda', + 'ZP' => 'Zopo', + 'ZT' => 'ZTE', + 'ZU' => 'Zuum', + 'ZN' => 'Zen', + 'ZY' => 'Zync', + 'ZQ' => 'ZYQ', + 'XT' => 'X-TIGI', + 'XB' => 'NEXBOX', + + // legacy brands, might be removed in future versions + 'WB' => 'Web TV', + 'XX' => 'Unknown' + ); + + public function getDeviceType() + { + return $this->deviceType; + } + + /** + * Returns available device types + * + * @see $deviceTypes + * @return array + */ + public static function getAvailableDeviceTypes() + { + return self::$deviceTypes; + } + + /** + * Returns names of all available device types + * + * @return array + */ + public static function getAvailableDeviceTypeNames() + { + return array_keys(self::$deviceTypes); + } + + /** + * Returns the name of the given device type + * + * @param int $deviceType one of the DEVICE_TYPE_* constants + * + * @return mixed + */ + public static function getDeviceName($deviceType) + { + return array_search($deviceType, self::$deviceTypes); + } + + /** + * Returns the detected device model + * + * @return string + */ + public function getModel() + { + return $this->model; + } + + /** + * Returns the detected device brand + * + * @return string + */ + public function getBrand() + { + return $this->brand; + } + + /** + * Returns the full brand name for the given short name + * + * @param string $brandId short brand name + * @return string + */ + public static function getFullName($brandId) + { + if (array_key_exists($brandId, self::$deviceBrands)) { + return self::$deviceBrands[$brandId]; + } + + return ''; + } + + /** + * Sets the useragent to be parsed + * + * @param string $userAgent + */ + public function setUserAgent($userAgent) + { + $this->reset(); + parent::setUserAgent($userAgent); + } + + public function parse() + { + $regexes = $this->getRegexes(); + foreach ($regexes as $brand => $regex) { + $matches = $this->matchUserAgent($regex['regex']); + if ($matches) { + break; + } + } + + if (empty($matches)) { + return false; + } + + if ($brand != 'Unknown') { + $brandId = array_search($brand, self::$deviceBrands); + if ($brandId === false) { + // This Exception should never be thrown. If so a defined brand name is missing in $deviceBrands + throw new \Exception("The brand with name '$brand' should be listed in the deviceBrands array. Tried to parse user agent: ".$this->userAgent); // @codeCoverageIgnore + } + $this->brand = $brandId; + } + + if (isset($regex['device']) && in_array($regex['device'], self::$deviceTypes)) { + $this->deviceType = self::$deviceTypes[$regex['device']]; + } + + $this->model = ''; + if (isset($regex['model'])) { + $this->model = $this->buildModel($regex['model'], $matches); + } + + if (isset($regex['models'])) { + foreach ($regex['models'] as $modelRegex) { + $modelMatches = $this->matchUserAgent($modelRegex['regex']); + if ($modelMatches) { + break; + } + } + + if (empty($modelMatches)) { + return true; + } + + $this->model = trim($this->buildModel($modelRegex['model'], $modelMatches)); + + if (isset($modelRegex['brand']) && $brandId = array_search($modelRegex['brand'], self::$deviceBrands)) { + $this->brand = $brandId; + } + + if (isset($modelRegex['device']) && in_array($modelRegex['device'], self::$deviceTypes)) { + $this->deviceType = self::$deviceTypes[$modelRegex['device']]; + } + } + + return true; + } + + protected function buildModel($model, $matches) + { + $model = $this->buildByMatch($model, $matches); + + $model = str_replace('_', ' ', $model); + + $model = preg_replace('/ TD$/i', '', $model); + + if ($model === 'Build') { + return null; + } + + return $model; + } + + protected function reset() + { + $this->deviceType = null; + $this->model = null; + $this->brand = null; + } +} diff --git a/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Device/HbbTv.php b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Device/HbbTv.php new file mode 100644 index 000000000..31561750f --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Device/HbbTv.php @@ -0,0 +1,53 @@ +isHbbTv()) { + return false; + } + + parent::parse(); + + // always set device type to tv, even if no model/brand could be found + $this->deviceType = self::DEVICE_TYPE_TV; + + return true; + } + + /** + * Returns if the parsed UA was identified as a HbbTV device + * + * @return bool + */ + public function isHbbTv() + { + $regex = 'HbbTV/([1-9]{1}(?:\.[0-9]{1}){1,2})'; + $match = $this->matchUserAgent($regex); + return $match ? $match[1] : false; + } +} diff --git a/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Device/Mobile.php b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Device/Mobile.php new file mode 100644 index 000000000..bc8763f4d --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/Device/Mobile.php @@ -0,0 +1,21 @@ +preMatchOverall()) { + return false; + } + + return parent::parse(); + } +} diff --git a/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/OperatingSystem.php b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/OperatingSystem.php new file mode 100644 index 000000000..c1c328c10 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/OperatingSystem.php @@ -0,0 +1,250 @@ + 'AIX', + 'AND' => 'Android', + 'AMG' => 'AmigaOS', + 'ATV' => 'Apple TV', + 'ARL' => 'Arch Linux', + 'BTR' => 'BackTrack', + 'SBA' => 'Bada', + 'BEO' => 'BeOS', + 'BLB' => 'BlackBerry OS', + 'QNX' => 'BlackBerry Tablet OS', + 'BMP' => 'Brew', + 'CES' => 'CentOS', + 'COS' => 'Chrome OS', + 'CYN' => 'CyanogenMod', + 'DEB' => 'Debian', + 'DFB' => 'DragonFly', + 'FED' => 'Fedora', + 'FOS' => 'Firefox OS', + 'FIR' => 'Fire OS', + 'BSD' => 'FreeBSD', + 'GNT' => 'Gentoo', + 'GTV' => 'Google TV', + 'HPX' => 'HP-UX', + 'HAI' => 'Haiku OS', + 'IRI' => 'IRIX', + 'INF' => 'Inferno', + 'KOS' => 'KaiOS', + 'KNO' => 'Knoppix', + 'KBT' => 'Kubuntu', + 'LIN' => 'GNU/Linux', + 'LBT' => 'Lubuntu', + 'VLN' => 'VectorLinux', + 'MAC' => 'Mac', + 'MAE' => 'Maemo', + 'MDR' => 'Mandriva', + 'SMG' => 'MeeGo', + 'MCD' => 'MocorDroid', + 'MIN' => 'Mint', + 'MLD' => 'MildWild', + 'MOR' => 'MorphOS', + 'NBS' => 'NetBSD', + 'MTK' => 'MTK / Nucleus', + 'WII' => 'Nintendo', + 'NDS' => 'Nintendo Mobile', + 'OS2' => 'OS/2', + 'T64' => 'OSF1', + 'OBS' => 'OpenBSD', + 'ORD' => 'Ordissimo', + 'PSP' => 'PlayStation Portable', + 'PS3' => 'PlayStation', + 'RHT' => 'Red Hat', + 'ROS' => 'RISC OS', + 'REM' => 'Remix OS', + 'RZD' => 'RazoDroiD', + 'SAB' => 'Sabayon', + 'SSE' => 'SUSE', + 'SAF' => 'Sailfish OS', + 'SLW' => 'Slackware', + 'SOS' => 'Solaris', + 'SYL' => 'Syllable', + 'SYM' => 'Symbian', + 'SYS' => 'Symbian OS', + 'S40' => 'Symbian OS Series 40', + 'S60' => 'Symbian OS Series 60', + 'SY3' => 'Symbian^3', + 'TDX' => 'ThreadX', + 'TIZ' => 'Tizen', + 'UBT' => 'Ubuntu', + 'WTV' => 'WebTV', + 'WIN' => 'Windows', + 'WCE' => 'Windows CE', + 'WIO' => 'Windows IoT', + 'WMO' => 'Windows Mobile', + 'WPH' => 'Windows Phone', + 'WRT' => 'Windows RT', + 'XBX' => 'Xbox', + 'XBT' => 'Xubuntu', + 'YNS' => 'YunOs', + 'IOS' => 'iOS', + 'POS' => 'palmOS', + 'WOS' => 'webOS' + ); + + /** + * Operating system families mapped to the short codes of the associated operating systems + * + * @var array + */ + protected static $osFamilies = array( + 'Android' => array('AND', 'CYN', 'FIR', 'REM', 'RZD', 'MLD', 'MCD', 'YNS'), + 'AmigaOS' => array('AMG', 'MOR'), + 'Apple TV' => array('ATV'), + 'BlackBerry' => array('BLB', 'QNX'), + 'Brew' => array('BMP'), + 'BeOS' => array('BEO', 'HAI'), + 'Chrome OS' => array('COS'), + 'Firefox OS' => array('FOS', 'KOS'), + 'Gaming Console' => array('WII', 'PS3'), + 'Google TV' => array('GTV'), + 'IBM' => array('OS2'), + 'iOS' => array('IOS'), + 'RISC OS' => array('ROS'), + 'GNU/Linux' => array('LIN', 'ARL', 'DEB', 'KNO', 'MIN', 'UBT', 'KBT', 'XBT', 'LBT', 'FED', 'RHT', 'VLN', 'MDR', 'GNT', 'SAB', 'SLW', 'SSE', 'CES', 'BTR', 'SAF', 'ORD'), + 'Mac' => array('MAC'), + 'Mobile Gaming Console' => array('PSP', 'NDS', 'XBX'), + 'Real-time OS' => array('MTK', 'TDX'), + 'Other Mobile' => array('WOS', 'POS', 'SBA', 'TIZ', 'SMG', 'MAE'), + 'Symbian' => array('SYM', 'SYS', 'SY3', 'S60', 'S40'), + 'Unix' => array('SOS', 'AIX', 'HPX', 'BSD', 'NBS', 'OBS', 'DFB', 'SYL', 'IRI', 'T64', 'INF'), + 'WebTV' => array('WTV'), + 'Windows' => array('WIN'), + 'Windows Mobile' => array('WPH', 'WMO', 'WCE', 'WRT', 'WIO') + ); + + /** + * Returns all available operating systems + * + * @return array + */ + public static function getAvailableOperatingSystems() + { + return self::$operatingSystems; + } + + /** + * Returns all available operating system families + * + * @return array + */ + public static function getAvailableOperatingSystemFamilies() + { + return self::$osFamilies; + } + + public function parse() + { + $return = array(); + + foreach ($this->getRegexes() as $osRegex) { + $matches = $this->matchUserAgent($osRegex['regex']); + if ($matches) { + break; + } + } + + if (!$matches) { + return $return; + } + + $name = $this->buildByMatch($osRegex['name'], $matches); + $short = 'UNK'; + + foreach (self::$operatingSystems as $osShort => $osName) { + if (strtolower($name) == strtolower($osName)) { + $name = $osName; + $short = $osShort; + } + } + + $return = array( + 'name' => $name, + 'short_name' => $short, + 'version' => $this->buildVersion($osRegex['version'], $matches), + 'platform' => $this->parsePlatform() + ); + + if (in_array($return['name'], self::$operatingSystems)) { + $return['short_name'] = array_search($return['name'], self::$operatingSystems); + } + + return $return; + } + + protected function parsePlatform() + { + if ($this->matchUserAgent('arm')) { + return 'ARM'; + } elseif ($this->matchUserAgent('WOW64|x64|win64|amd64|x86_64')) { + return 'x64'; + } elseif ($this->matchUserAgent('i[0-9]86|i86pc')) { + return 'x86'; + } + + return ''; + } + + + /** + * Returns the operating system family for the given operating system + * + * @param $osLabel + * @return bool|string If false, "Unknown" + */ + public static function getOsFamily($osLabel) + { + foreach (self::$osFamilies as $family => $labels) { + if (in_array($osLabel, $labels)) { + return $family; + } + } + return false; + } + + /** + * Returns the full name for the given short name + * + * @param $os + * @param bool $ver + * + * @return bool|string + */ + public static function getNameFromId($os, $ver = false) + { + if (array_key_exists($os, self::$operatingSystems)) { + $osFullName = self::$operatingSystems[$os]; + return trim($osFullName . " " . $ver); + } + return false; + } +} diff --git a/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/ParserAbstract.php b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/ParserAbstract.php new file mode 100644 index 000000000..97b07c6ce --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/ParserAbstract.php @@ -0,0 +1,329 @@ +setUserAgent($ua); + } + + /** + * Set how DeviceDetector should return versions + * @param int|null $type Any of the VERSION_TRUNCATION_* constants + */ + public static function setVersionTruncation($type) + { + if (in_array($type, array(self::VERSION_TRUNCATION_BUILD, + self::VERSION_TRUNCATION_NONE, + self::VERSION_TRUNCATION_MAJOR, + self::VERSION_TRUNCATION_MINOR, + self::VERSION_TRUNCATION_PATCH))) { + self::$maxMinorParts = $type; + } + } + + /** + * Sets the user agent to parse + * + * @param string $ua user agent + */ + public function setUserAgent($ua) + { + $this->userAgent = $ua; + } + + /** + * Returns the internal name of the parser + * + * @return string + */ + public function getName() + { + return $this->parserName; + } + + /** + * Returns the result of the parsed yml file defined in $fixtureFile + * + * @return array + */ + protected function getRegexes() + { + if (empty($this->regexList)) { + $cacheKey = 'DeviceDetector-'.DeviceDetector::VERSION.'regexes-'.$this->getName(); + $cacheKey = preg_replace('/([^a-z0-9_-]+)/i', '', $cacheKey); + $this->regexList = $this->getCache()->fetch($cacheKey); + if (empty($this->regexList)) { + $this->regexList = $this->getYamlParser()->parseFile( + $this->getRegexesDirectory().DIRECTORY_SEPARATOR.$this->fixtureFile + ); + $this->getCache()->save($cacheKey, $this->regexList); + } + } + return $this->regexList; + } + + /** + * @return string + */ + protected function getRegexesDirectory() + { + return dirname(__DIR__); + } + + /** + * Matches the useragent against the given regex + * + * @param string $regex + * @return array|bool + */ + protected function matchUserAgent($regex) + { + // only match if useragent begins with given regex or there is no letter before it + $regex = '/(?:^|[^A-Z0-9\-_]|[^A-Z0-9\-]_|sprd-)(?:' . str_replace('/', '\/', $regex) . ')/i'; + + if (preg_match($regex, $this->userAgent, $matches)) { + return $matches; + } + + return false; + } + + /** + * @param string $item + * @param array $matches + * @return string type + */ + protected function buildByMatch($item, $matches) + { + for ($nb=1;$nb<=3;$nb++) { + if (strpos($item, '$' . $nb) === false) { + continue; + } + + $replace = isset($matches[$nb]) ? $matches[$nb] : ''; + $item = trim(str_replace('$' . $nb, $replace, $item)); + } + return $item; + } + + /** + * Builds the version with the given $versionString and $matches + * + * Example: + * $versionString = 'v$2' + * $matches = array('version_1_0_1', '1_0_1') + * return value would be v1.0.1 + * + * @param $versionString + * @param $matches + * @return mixed|string + */ + protected function buildVersion($versionString, $matches) + { + $versionString = $this->buildByMatch($versionString, $matches); + $versionString = str_replace('_', '.', $versionString); + if (null !== self::$maxMinorParts && substr_count($versionString, '.') > self::$maxMinorParts) { + $versionParts = explode('.', $versionString); + $versionParts = array_slice($versionParts, 0, 1+self::$maxMinorParts); + $versionString = implode('.', $versionParts); + } + return trim($versionString, ' .'); + } + + /** + * Tests the useragent against a combination of all regexes + * + * All regexes returned by getRegexes() will be reversed and concated with '|' + * Afterwards the big regex will be tested against the user agent + * + * Method can be used to speed up detections by making a big check before doing checks for every single regex + * + * @return bool + */ + protected function preMatchOverall() + { + $regexes = $this->getRegexes(); + + static $overAllMatch; + + $cacheKey = $this->parserName.DeviceDetector::VERSION.'-all'; + $cacheKey = preg_replace('/([^a-z0-9_-]+)/i', '', $cacheKey); + + if (empty($overAllMatch)) { + $overAllMatch = $this->getCache()->fetch($cacheKey); + } + + if (empty($overAllMatch)) { + // reverse all regexes, so we have the generic one first, which already matches most patterns + $overAllMatch = array_reduce(array_reverse($regexes), function ($val1, $val2) { + if (!empty($val1)) { + return $val1.'|'.$val2['regex']; + } else { + return $val2['regex']; + } + }); + $this->getCache()->save($cacheKey, $overAllMatch); + } + + return $this->matchUserAgent($overAllMatch); + } + + /** + * Sets the Cache class + * + * @param Cache|\Doctrine\Common\Cache\CacheProvider $cache + * @throws \Exception + */ + public function setCache($cache) + { + if ($cache instanceof Cache || + (class_exists('\Doctrine\Common\Cache\CacheProvider') && $cache instanceof \Doctrine\Common\Cache\CacheProvider)) { + $this->cache = $cache; + return; + } + + throw new \Exception('Cache not supported'); + } + + /** + * Returns Cache object + * + * @return Cache|\Doctrine\Common\Cache\CacheProvider + */ + public function getCache() + { + if (!empty($this->cache)) { + return $this->cache; + } + + return new StaticCache(); + } + + /** + * Sets the YamlParser class + * + * @param YamlParser + * @throws \Exception + */ + public function setYamlParser($yamlParser) + { + if ($yamlParser instanceof YamlParser) { + $this->yamlParser = $yamlParser; + return; + } + + throw new \Exception('Yaml Parser not supported'); + } + + /** + * Returns YamlParser object + * + * @return YamlParser + */ + public function getYamlParser() + { + if (!empty($this->yamlParser)) { + return $this->yamlParser; + } + + return new Spyc(); + } +} diff --git a/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/VendorFragment.php b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/VendorFragment.php new file mode 100644 index 000000000..4abbbe8f2 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Parser/VendorFragment.php @@ -0,0 +1,44 @@ +getRegexes() as $brand => $regexes) { + foreach ($regexes as $regex) { + if ($this->matchUserAgent($regex.'[^a-z0-9]+')) { + $this->matchedRegex = $regex; + return array_search($brand, DeviceParserAbstract::$deviceBrands); + } + } + } + + return ''; + } + + public function getMatchedRegex() + { + return $this->matchedRegex; + } +} diff --git a/plugins/vdomah/blogviews/vendor/piwik/device-detector/README.md b/plugins/vdomah/blogviews/vendor/piwik/device-detector/README.md new file mode 100644 index 000000000..ca8d6e9ff --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/piwik/device-detector/README.md @@ -0,0 +1,241 @@ +DeviceDetector +============== + +[![Latest Stable Version](https://poser.pugx.org/piwik/device-detector/v/stable)](https://packagist.org/packages/piwik/device-detector) +[![Latest Unstable Version](https://poser.pugx.org/piwik/device-detector/v/unstable)](https://packagist.org/packages/piwik/device-detector) +[![Total Downloads](https://poser.pugx.org/piwik/device-detector/downloads)](https://packagist.org/packages/piwik/device-detector) +[![License](https://poser.pugx.org/piwik/device-detector/license)](https://packagist.org/packages/piwik/device-detector) + +## Code Status + +[![Build Status](https://travis-ci.org/matomo-org/device-detector.svg?branch=master)](https://travis-ci.org/matomo-org/device-detector) +[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/matomo-org/device-detector.svg)](http://isitmaintained.com/project/matomo-org/device-detector "Average time to resolve an issue") +[![Percentage of issues still open](http://isitmaintained.com/badge/open/matomo-org/device-detector.svg)](http://isitmaintained.com/project/matomo-org/device-detector "Percentage of issues still open") + +## Description + +The Universal Device Detection library that parses User Agents and detects devices (desktop, tablet, mobile, tv, cars, console, etc.), clients (browsers, feed readers, media players, PIMs, ...), operating systems, brands and models. + +## Usage + +Using DeviceDetector with composer is quite easy. Just add piwik/device-detector to your projects requirements. And use some code like this one: + + +```php +require_once 'vendor/autoload.php'; + +use DeviceDetector\DeviceDetector; +use DeviceDetector\Parser\Device\DeviceParserAbstract; + +// OPTIONAL: Set version truncation to none, so full versions will be returned +// By default only minor versions will be returned (e.g. X.Y) +// for other options see VERSION_TRUNCATION_* constants in DeviceParserAbstract class +DeviceParserAbstract::setVersionTruncation(DeviceParserAbstract::VERSION_TRUNCATION_NONE); + +$userAgent = $_SERVER['HTTP_USER_AGENT']; // change this to the useragent you want to parse + +$dd = new DeviceDetector($userAgent); + +// OPTIONAL: Set caching method +// By default static cache is used, which works best within one php process (memory array caching) +// To cache across requests use caching in files or memcache +// $dd->setCache(new Doctrine\Common\Cache\PhpFileCache('./tmp/')); + +// OPTIONAL: Set custom yaml parser +// By default Spyc will be used for parsing yaml files. You can also use another yaml parser. +// You may need to implement the Yaml Parser facade if you want to use another parser than Spyc or [Symfony](https://github.com/symfony/yaml) +// $dd->setYamlParser(new DeviceDetector\Yaml\Symfony()); + +// OPTIONAL: If called, getBot() will only return true if a bot was detected (speeds up detection a bit) +// $dd->discardBotInformation(); + +// OPTIONAL: If called, bot detection will completely be skipped (bots will be detected as regular devices then) +// $dd->skipBotDetection(); + +$dd->parse(); + +if ($dd->isBot()) { + // handle bots,spiders,crawlers,... + $botInfo = $dd->getBot(); +} else { + $clientInfo = $dd->getClient(); // holds information about browser, feed reader, media player, ... + $osInfo = $dd->getOs(); + $device = $dd->getDeviceName(); + $brand = $dd->getBrandName(); + $model = $dd->getModel(); +} +``` + +Instead of using the full power of DeviceDetector it might in some cases be better to use only specific parsers. +If you aim to check if a given useragent is a bot and don't require any of the other information, you can directly use the bot parser. + +```php +require_once 'vendor/autoload.php'; + +use DeviceDetector\Parser\Bot AS BotParser; + +$botParser = new BotParser(); +$botParser->setUserAgent($userAgent); + +// OPTIONAL: discard bot information. parse() will then return true instead of information +$botParser->discardDetails(); + +$result = $botParser->parse(); + +if (!is_null($result)) { + // do not do anything if a bot is detected + return; +} + +// handle non-bot requests + +``` + +## Using without composer + +Alternatively to using composer you can also use the included `autoload.php`. +This script will register an autoloader to dynamically load all classes in `DeviceDetector` namespace. + +Device Detector requires a YAML parser. By default `Spyc` parser is used. +As this library is not included you need to include it manually or use another YAML parser. + +```php +setCache( + new DeviceDetector\Cache\PSR6Bridge($cache) +); + +// Example with PSR-16 and ScrapBook +$cache = new \MatthiasMullie\Scrapbook\Psr16\SimpleCache( + new \MatthiasMullie\Scrapbook\Adapters\Apc() +); +$dd->setCache( + new DeviceDetector\Cache\PSR16Bridge($cache) +); + +// Example with Doctrine +$dd->setCache( + new Doctrine\Common\Cache\ApcuCache() +); +``` + +## Contributing + +### Hacking the library + +This is a free/libre library under license LGPL v3 or later. + +Your pull requests and/or feedback is very welcome! + +### Listing all user agents from your logs +Sometimes it may be useful to generate the list of most used user agents on your website, +extracting this list from your access logs using the following command: + +``` +zcat ~/path/to/access/logs* | awk -F'"' '{print $6}' | sort | uniq -c | sort -rn | head -n20000 > /home/matomo/top-user-agents.txt +``` + +### Contributors +Created by the [Matomo team](http://matomo.org/team/), Stefan Giehl, Matthieu Aubry, Michał Gaździk, +Tomasz Majczak, Grzegorz Kaszuba, Piotr Banaszczyk and contributors. + +Together we can build the best Device Detection library. + +We are looking forward to your contributions and pull requests! + +## Tests + +See also: [QA at Matomo](http://matomo.org/qa/) + +### Running tests + +``` +cd /path/to/device-detector +curl -sS https://getcomposer.org/installer | php +php composer.phar install +./vendor/bin/phpunit +``` + +## Device Detector for other languages + +There are already a few ports of this tool to other languages: + +- **.NET** https://github.com/AgileFlexAgency/MatomoDeviceDetector.NET +- **.NET** https://github.com/totpero/DeviceDetector.NET +- **Ruby** https://github.com/podigee/device_detector +- **JavaScript/TypeScript/NodeJS** https://github.com/etienne-martin/device-detector-js +- **Python 3** https://github.com/thinkwelltwd/device_detector +- **Crystal** https://github.com/creadone/device_detector +- **Elixir** https://github.com/elixir-inspector/ua_inspector +- **Java** https://github.com/mngsk/device-detector + + +## What Device Detector is able to detect + +The lists below are auto generated and updated from time to time. Some of them might not be complete. + +*Last update: 2020/03/31* + +### List of detected operating systems: + +AIX, Android, AmigaOS, Apple TV, Arch Linux, BackTrack, Bada, BeOS, BlackBerry OS, BlackBerry Tablet OS, Brew, CentOS, Chrome OS, CyanogenMod, Debian, DragonFly, Fedora, Firefox OS, Fire OS, FreeBSD, Gentoo, Google TV, HP-UX, Haiku OS, IRIX, Inferno, KaiOS, Knoppix, Kubuntu, GNU/Linux, Lubuntu, VectorLinux, Mac, Maemo, Mandriva, MeeGo, MocorDroid, Mint, MildWild, MorphOS, NetBSD, MTK / Nucleus, Nintendo, Nintendo Mobile, OS/2, OSF1, OpenBSD, Ordissimo, PlayStation Portable, PlayStation, Red Hat, RISC OS, Remix OS, RazoDroiD, Sabayon, SUSE, Sailfish OS, Slackware, Solaris, Syllable, Symbian, Symbian OS, Symbian OS Series 40, Symbian OS Series 60, Symbian^3, ThreadX, Tizen, Ubuntu, WebTV, Windows, Windows CE, Windows IoT, Windows Mobile, Windows Phone, Windows RT, Xbox, Xubuntu, YunOs, iOS, palmOS, webOS + +### List of detected browsers: + +2345 Browser, 360 Phone Browser, 360 Browser, Avant Browser, ABrowse, ANT Fresco, ANTGalio, Aloha Browser, Aloha Browser Lite, Amaya, Amigo, Android Browser, AOL Shield, Arora, Amiga Voyager, Amiga Aweb, Atomic Web Browser, Avast Secure Browser, AVG Secure Browser, Beaker Browser, Beamrise, BlackBerry Browser, Baidu Browser, Baidu Spark, Basilisk, Beonex, BlackHawk, Bunjalloo, B-Line, Brave, BriskBard, BrowseX, Camino, CCleaner, Coc Coc, Comodo Dragon, Coast, Charon, CM Browser, Chrome Frame, Headless Chrome, Chrome, Chrome Mobile iOS, Conkeror, Chrome Mobile, CoolNovo, CometBird, COS Browser, ChromePlus, Chromium, Cyberfox, Cheshire, Crusta, Cunaguaro, Chrome Webview, dbrowser, Deepnet Explorer, Delta Browser, Dolphin, Dorado, Dooble, Dillo, DuckDuckGo Privacy Browser, Ecosia, Epic, Elinks, Element Browser, eZ Browser, EUI Browser, GNOME Web, Espial TV Browser, Falkon, Faux Browser, Firefox Mobile iOS, Firebird, Fluid, Fennec, Firefox, Firefox Focus, Firefox Reality, Firefox Rocket, Flock, Firefox Mobile, Fireweb, Fireweb Navigator, FreeU, Galeon, Google Earth, Hawk Turbo Browser, hola! Browser, HotJava, Huawei Browser, IBrowse, iCab, iCab Mobile, Iridium, Iron Mobile, IceCat, IceDragon, Isivioo, Iceweasel, Internet Explorer, IE Mobile, Iron, Jasmine, Jig Browser, Jio Browser, K.Browser, Kindle Browser, K-meleon, Konqueror, Kapiko, Kinza, Kiwi, Kylo, Kazehakase, Cheetah Browser, LieBaoFast, LG Browser, Links, Lovense Browser, LuaKit, Lunascape, Lynx, mCent, MicroB, NCSA Mosaic, Meizu Browser, Mercury, Mobile Safari, Midori, Mobicip, MIUI Browser, Mobile Silk, Minimo, Mint Browser, Maxthon, Nokia Browser, Nokia OSS Browser, Nokia Ovi Browser, Nox Browser, NetSurf, NetFront, NetFront Life, NetPositive, Netscape, NTENT Browser, Oculus Browser, Opera Mini iOS, Obigo, Odyssey Web Browser, Off By One, ONE Browser, Opera GX, Opera Neon, Opera Devices, Opera Mini, Opera Mobile, Opera, Opera Next, Opera Touch, Ordissimo, Oregano, Origyn Web Browser, Openwave Mobile Browser, OmniWeb, Otter Browser, Palm Blazer, Pale Moon, Oppo Browser, Palm Pre, Puffin, Palm WebPro, Palmscape, Phoenix, Polaris, Polarity, Microsoft Edge, QQ Browser Mini, QQ Browser, Qutebrowser, QupZilla, Qwant Mobile, QtWebEngine, Realme Browser, Rekonq, RockMelt, Samsung Browser, Sailfish Browser, SEMC-Browser, Sogou Explorer, Safari, SalamWeb, Shiira, SimpleBrowser, Skyfire, Seraphic Sraf, Sleipnir, Snowshoe, Sogou Mobile Browser, Splash, Sputnik Browser, Sunrise, SuperBird, Super Fast Browser, START Internet Browser, Streamy, Swiftfox, Seznam Browser, t-online.de Browser, Tao Browser, TenFourFox, Tenta Browser, Tizen Browser, TweakStyle, TV Bro, UBrowser, UC Browser, UC Browser Mini, UC Browser Turbo, Uzbl, Vivaldi, vivo Browser, Vision Mobile Browser, Wear Internet Browser, Web Explorer, WebPositive, Waterfox, Whale Browser, wOSBrowser, WeTab Browser, Yandex Browser, Yandex Browser Lite, Xiino + +### List of detected browser engines: + +WebKit, Blink, Trident, Text-based, Dillo, iCab, Elektra, Presto, Gecko, KHTML, NetFront, Edge, NetSurf, Servo + +### List of detected libraries: + +aiohttp, curl, Faraday, Go-http-client, Google HTTP Java Client, Guzzle (PHP HTTP Client), HTTPie, HTTP_Request2, Java, libdnf, Mechanize, Node Fetch, OkHttp, Perl, Perl REST::Client, Python Requests, Python urllib, REST Client for Ruby, RestSharp, ScalaJ HTTP, urlgrabber (yum), Wget, WWW-Mechanize + +### List of detected media players: + +Audacious, Banshee, Boxee, Clementine, Deezer, FlyCast, Foobar2000, Google Podcasts, iTunes, Kodi, MediaMonkey, Miro, mpv, Music Player Daemon, NexPlayer, Nightingale, QuickTime, Songbird, Stagefright, SubStream, VLC, Winamp, Windows Media Player, XBMC + +### List of detected mobile apps: + +AndroidDownloadManager, AntennaPod, Apple News, Baidu Box App, BeyondPod, BingWebApp, bPod, CastBox, Castro, Castro 2, CrosswalkApp, DoggCatcher, douban App, Facebook, Facebook Messenger, FeedR, Flipboard App, Google Go, Google Play Newsstand, Google Plus, Google Search App, iCatcher, Instacast, Instagram App, Line, NewsArticle App, Overcast, Pinterest, Player FM, Pocket Casts, Podcast & Radio Addict, Podcast Republic, Podcasts, Podcat, Podcatcher Deluxe, Podkicker, RSSRadio, Sina Weibo, SogouSearch App, tieba, WeChat, WhatsApp, Yahoo! Japan, Yelp Mobile, YouTube and *mobile apps using [AFNetworking](https://github.com/AFNetworking/AFNetworking)* + +### List of detected PIMs (personal information manager): + +Airmail, Barca, DAVdroid, Lotus Notes, MailBar, Microsoft Outlook, Outlook Express, Postbox, SeaMonkey, The Bat!, Thunderbird + +### List of detected feed readers: + +Akregator, Apple PubSub, BashPodder, Breaker, Downcast, FeedDemon, Feeddler RSS Reader, gPodder, JetBrains Omea Reader, Liferea, NetNewsWire, Newsbeuter, NewsBlur, NewsBlur Mobile App, PritTorrent, Pulp, QuiteRSS, ReadKit, Reeder, RSS Bandit, RSS Junkie, RSSOwl, Stringer + +### List of brands with detected devices: + +3Q, 4Good, Ace, Acer, Advan, Advance, AGM, Ainol, Airness, Airties, AIS, Aiwa, Akai, Alba, Alcatel, Aligator, AllCall, AllDocube, Allview, Allwinner, Altech UEC, altron, Amazon, AMGOO, Amoi, ANS, Apple, Archos, Arian Space, Ark, Arnova, ARRIS, Ask, Assistant, Asus, Atom, Audiovox, AVH, Avvio, Axxion, Azumi Mobile, BangOlufsen, Barnes & Noble, BBK, BDF, Becker, Beeline, Beetel, BenQ, BenQ-Siemens, Bezkam, BGH, Bird, Bitel, Black Fox, Blackview, Blaupunkt, Blu, Bluboo, Bluegood, Bmobile, bogo, Boway, bq, Bravis, Brondi, Bush, CAGI, Capitel, Captiva, Carrefour, Casio, Casper, Cat, Celkon, Changhong, Cherry Mobile, China Mobile, Chuwi, Clarmin, CnM, Coby Kyros, Comio, Compal, Compaq, ComTrade Tesla, Concord, ConCorde, Condor, Coolpad, Cowon, CreNova, Crescent, Cricket, Crius Mea, Crosscall, Cube, CUBOT, CVTE, Cyrus, Daewoo, Danew, Datang, Datsun, Dbtel, Dell, Denver, Desay, DeWalt, DEXP, Dialog, Dicam, Digi, Digicel, Digiland, Digma, Divisat, DMM, DNS, DoCoMo, Doogee, Doov, Dopod, Doro, Dune HD, E-Boda, E-tel, Easypix, EBEST, Echo Mobiles, ECS, EE, EKO, Eks Mobility, Elenberg, Elephone, Energizer, Energy Sistem, Ergo, Ericsson, Ericy, Essential, Essentielb, Eton, eTouch, Etuline, Eurostar, Evercoss, Evertek, Evolio, Evolveo, EvroMedia, Explay, Extrem, Ezio, Ezze, Fairphone, Famoco, Fengxiang, FiGO, FinePower, Fly, FNB, Fondi, FORME, Forstar, Foxconn, Freetel, Fujitsu, G-TiDE, Garmin-Asus, Gateway, Gemini, General Mobile, Geotel, Ghia, Ghong, Gigabyte, Gigaset, Ginzzu, Gionee, Globex, GOCLEVER, Goly, GoMobile, Google, Gradiente, Grape, Grundig, Hafury, Haier, HannSpree, Hasee, Hi-Level, Highscreen, Hisense, Hoffmann, Homtom, Hoozo, Hosin, HP, HTC, Huawei, Humax, Hyrican, Hyundai, i-Joy, i-mate, i-mobile, iBall, iBerry, IconBIT, iHunt, Ikea, iKoMo, iLA, IMO Mobile, Impression, iNew, Infinix, InFocus, Inkti, InnJoo, Innostream, Inoi, INQ, Insignia, Intek, Intex, Inverto, iOcean, iPro, Irbis, iRola, iRulu, iTel, iView, iZotron, JAY-Tech, Jiayu, Jolla, Just5, K-Touch, Kaan, Kaiomy, Kalley, Kanji, Karbonn, KATV1, Kazam, KDDI, Kempler & Strauss, Keneksi, Kiano, Kingsun, Kivi, Kocaso, Kodak, Kogan, Komu, Konka, Konrow, Koobee, KOPO, Koridy, KRONO, Krüger&Matz, KT-Tech, Kumai, Kyocera, LAIQ, Land Rover, Landvo, Lanix, Lark, Lava, LCT, Leagoo, Ledstar, LeEco, Lemhoov, Lenco, Lenovo, Leotec, Le Pan, Lephone, Lexand, Lexibook, LG, Lingwin, Loewe, Logicom, Lumus, Luna, LYF, M.T.T., M4tel, Majestic, Mann, Manta Multimedia, Masstel, Maxcom, Maxwest, Maze, Mecer, Mecool, Mediacom, MediaTek, Medion, MEEG, MegaFon, Meitu, Meizu, Memup, Metz, MEU, MicroMax, Microsoft, Mio, Miray, Mitsubishi, MIXC, MLLED, Mobicel, Mobiistar, Mobiola, Mobistel, Modecom, Mofut, Motorola, Movic, Mpman, MSI, MTC, MTN, MYFON, MyPhone, Myria, Mystery, MyWigo, National, Navon, NEC, Neffos, Netgear, NeuImage, Newgen, NewsMy, NEXBOX, Nexian, Nextbit, NextBook, NGM, NG Optics, Nikon, Nintendo, NOA, Noain, Nobby, Noblex, Nokia, Nomi, Nous, NUU Mobile, Nuvo, Nvidia, NYX Mobile, O+, O2, Obi, Odys, Onda, OnePlus, OPPO, Opsson, Orange, Ordissimo, Ouki, Oukitel, OUYA, Overmax, Oysters, Palm, Panacom, Panasonic, Pantech, PCBOX, PCD, PCD Argentina, PEAQ, Pentagram, Philips, phoneOne, Pioneer, Pixus, Ployer, Plum, Point of View, Polaroid, PolyPad, Polytron, Pomp, Positivo, PPTV, Prestigio, Primepad, Proline, ProScan, PULID, Q-Touch, Qilive, QMobile, Qtek, Quantum, Quechua, Qumo, R-TV, Ramos, RCA Tablets, Readboy, Rikomagic, RIM, Rinno, Ritmix, Ritzviva, Riviera, Roadrover, Rokit, Roku, Rombica, Ross&Moor, Rover, RoverPad, RT Project, RugGear, Runbo, Safaricom, Sagem, Samsung, Sanei, Santin, Sanyo, Savio, Sega, Selevision, Selfix, Sencor, Sendo, Senseit, Senwa, SFR, Sharp, Shift Phones, Shuttle, Siemens, Sigma, Silent Circle, Simbans, Sky, Skyworth, Smart, Smartfren, Smartisan, Softbank, Sonim, Sony, Sony Ericsson, Spectrum, Spice, Star, Starway, STF Mobile, STK, Stonex, Storex, Sumvision, SunVan, Sunvell, SuperSonic, Supra, SWISSMOBILITY, Symphony, Syrox, T-Mobile, TB Touch, TCL, TechniSat, TechnoTrend, TechPad, Teclast, Tecno Mobile, Telefunken, Telego, Telenor, Telit, Tesco, Tesla, teXet, ThL, Thomson, TIANYU, Timovi, TiPhone, Tolino, Tooky, Top House, Toplux, Toshiba, Touchmate, TrekStor, Trevi, True, Tunisie Telecom, Turbo, Turbo-X, TVC, U.S. Cellular, Ugoos, Uhappy, Ulefone, Umax, UMIDIGI, Unihertz, Unimax, Uniscope, Unknown, Unnecto, Unonu, Unowhy, UTOK, UTStarcom, Vastking, Venso, Verizon, Vernee, Vertex, Vertu, Verykool, Vesta, Vestel, VGO TEL, Videocon, Videoweb, ViewSonic, Vinga, Vinsoc, Vitelcom, Vivax, Vivo, Vizio, VK Mobile, Vodafone, Vonino, Vorago, Voto, Voxtel, Vsun, Vulcan, Walton, Web TV, Weimei, WellcoM, Wexler, Wieppo, Wiko, Wileyfox, Wink, Wolder, Wolfgang, Wonu, Woo, Woxter, X-TIGI, X-View, Xiaolajiao, Xiaomi, Xion, Xolo, Xoro, Yandex, Yarvik, Yes, Yezz, Yota, Ytone, Yu, Yuandao, Yusun, Yxtel, Zeemi, Zen, Zenek, Zonda, Zopo, ZTE, Zuum, Zync, ZYQ, öwn + +### List of detected bots: + +360Spider, Aboundexbot, Acoon, AddThis.com, ADMantX, aHrefs Bot, Alexa Crawler, Alexa Site Audit, Amazon Route53 Health Check, Amorank Spider, Analytics SEO Crawler, ApacheBench, Applebot, Arachni, archive.org bot, Ask Jeeves, Awario, Awario, Backlink-Check.de, BacklinkCrawler, Baidu Spider, BazQux Reader, BingBot, BitlyBot, Blekkobot, BLEXBot Crawler, Bloglovin, Blogtrottr, BoardReader, BoardReader Blog Indexer, Bountii Bot, BrandVerity, Browsershots, BUbiNG, Buck, Butterfly Robot, Bytespider, CareerBot, Castro 2, Catchpoint, CATExplorador, ccBot crawler, Charlotte, Cliqzbot, CloudFlare Always Online, CloudFlare AMP Fetcher, Collectd, CommaFeed, CSS Certificate Spider, Cốc Cốc Bot, Datadog Agent, Datanyze, Dataprovider, Daum, Dazoobot, Discobot, Domain Re-Animator Bot, DotBot, DuckDuckGo Bot, Easou Spider, eCairn-Grabber, EMail Exractor, EmailWolf, Embedly, evc-batch, ExaBot, ExactSeek Crawler, Ezooms, eZ Publish Link Validator, Facebook External Hit, Feedbin, FeedBurner, Feedly, Feedspot, Feed Wrangler, Fever, Findxbot, Flipboard, FreshRSS, Generic Bot, Generic Bot, Genieo Web filter, Gigablast, Gigabot, Gluten Free Crawler, Gmail Image Proxy, Goo, Googlebot, Google Cloud Scheduler, Google Favicon, Google PageSpeed Insights, Google Partner Monitoring, Google Search Console, Google Stackdriver Monitoring, Google Structured Data Testing Tool, Grapeshot, Heritrix, Heureka Feed, HTTPMon, HubPages, HubSpot, ICC-Crawler, ichiro, IDG/IT, IIS Site Analysis, Inktomi Slurp, inoreader, IP-Guide Crawler, IPS Agent, Kaspersky, Kouio, Larbin web crawler, LCC, Let's Encrypt Validation, Lighthouse, Linkdex Bot, LinkedIn Bot, LTX71, Lycos, Magpie-Crawler, MagpieRSS, Mail.Ru Bot, masscan, Mastodon Bot, Meanpath Bot, MetaInspector, MetaJobBot, Mixrank Bot, MJ12 Bot, Mnogosearch, MojeekBot, Monitor.Us, Munin, Nagios check_http, NalezenCzBot, nbertaupete95, Netcraft Survey Bot, netEstate, NetLyzer FastProbe, NetResearchServer, Netvibes, NewsBlur, NewsGator, NLCrawler, Nmap, Nutch-based Bot, Nuzzel, oBot, Octopus, Omgili bot, Openindex Spider, OpenLinkProfiler, OpenWebSpider, Orange Bot, Outbrain, PagePeeker, PaperLiBot, Phantomas, PHP Server Monitor, Picsearch bot, Pingdom Bot, Pinterest, PocketParser, Pompos, PritTorrent, QuerySeekerSpider, Quora Link Preview, Qwantify, Rainmeter, RamblerMail Image Proxy, Reddit Bot, Riddler, Rogerbot, ROI Hunter, RSSRadio Bot, SafeDNSBot, Scooter, ScoutJet, Scrapy, Screaming Frog SEO Spider, ScreenerBot, Semrush Bot, Sensika Bot, Sentry Bot, SEOENGBot, SEOkicks-Robot, Seoscanners.net, Server Density, Seznam Bot, Seznam Email Proxy, Seznam Zbozi.cz, ShopAlike, Shopify Partner, ShopWiki, SilverReader, SimplePie, SISTRIX Crawler, SISTRIX Optimizer, Site24x7 Website Monitoring, Siteimprove, SiteSucker, Sixy.ch, Skype URI Preview, Slackbot, SMTBot, Snapchat Proxy, Sogou Spider, Soso Spider, Sparkler, Speedy, Spinn3r, Spotify, Sputnik Bot, sqlmap, SSL Labs, Startpagina Linkchecker, StatusCake, Superfeedr Bot, Survey Bot, Tarmot Gezgin, TelegramBot, The Knowledge AI, theoldreader, TinEye Crawler, Tiny Tiny RSS, TLSProbe, TraceMyFile, Trendiction Bot, TurnitinBot, TweetedTimes Bot, Tweetmeme Bot, Twingly Recon, Twitterbot, UkrNet Mail Proxy, UniversalFeedParser, Uptimebot, Uptime Robot, URLAppendBot, Vagabondo, Visual Site Mapper Crawler, VK Share Button, W3C CSS Validator, W3C I18N Checker, W3C Link Checker, W3C Markup Validation Service, W3C MobileOK Checker, W3C Unified Validator, Wappalyzer, WebbCrawler, Weborama, WebPageTest, WebSitePulse, WebThumbnail, WeSEE:Search, WikiDo, Willow Internet Crawler, WooRank, WordPress, Wotbox, YaCy, Yahoo! Cache System, Yahoo! Japan BRW, Yahoo! Link Preview, Yahoo! Slurp, Yahoo Gemini, Yandex Bot, Yeti/Naverbot, Yottaa Site Monitor, Youdao Bot, Yourls, Yunyun Bot, Zao, Ze List, zgrab, Zookabot, ZumBot diff --git a/plugins/vdomah/blogviews/vendor/piwik/device-detector/Yaml/Parser.php b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Yaml/Parser.php new file mode 100644 index 000000000..21f7f161a --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/piwik/device-detector/Yaml/Parser.php @@ -0,0 +1,14 @@ +parse(file_get_contents($file)); + } +} diff --git a/plugins/vdomah/blogviews/vendor/piwik/device-detector/autoload.php b/plugins/vdomah/blogviews/vendor/piwik/device-detector/autoload.php new file mode 100644 index 000000000..001b1af8c --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/piwik/device-detector/autoload.php @@ -0,0 +1,32 @@ +class. + * + * @param string $class + * the name of the class to load + * + * @return void + */ +function dd_autoload($class) +{ + if (strpos($class, 'DeviceDetector\\') !== false) { + $namespace_map = array('DeviceDetector\\' => __DIR__ . '/'); + foreach ($namespace_map as $prefix => $dir) + { + /* First swap out the namespace prefix with a directory... */ + $path = str_replace($prefix, $dir, $class); + /* replace the namespace separator with a directory separator... */ + $path = str_replace('\\', '/', $path); + /* and finally, add the PHP file extension to the result. */ + $path = $path . '.php'; + /* $path should now contain the path to a PHP file defining $class */ + @include $path; + } + } +} +spl_autoload_register('dd_autoload'); diff --git a/plugins/vdomah/blogviews/vendor/piwik/device-detector/composer.json b/plugins/vdomah/blogviews/vendor/piwik/device-detector/composer.json new file mode 100644 index 000000000..533e0f5c1 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/piwik/device-detector/composer.json @@ -0,0 +1,42 @@ +{ + "name": "piwik/device-detector", + "type": "library", + "description": "The Universal Device Detection library, that parses User Agents and detects devices (desktop, tablet, mobile, tv, cars, console, etc.), clients (browsers, media players, mobile apps, feed readers, libraries, etc), operating systems, devices, brands and models.", + "keywords": ["useragent","parser","devicedetection"], + "homepage": "https://matomo.org", + "license": "LGPL-3.0-or-later", + "authors": [ + { + "name": "The Matomo Team", + "email": "hello@matomo.org", + "homepage": "https://matomo.org/team/" + } + ], + "support": { + "forum": "http://forum.matomo.org/", + "issues": "https://github.com/matomo-org/device-detector/issues", + "wiki": "https://dev.matomo.org/", + "source": "https://github.com/matomo-org/piwik" + }, + "autoload": { + "psr-4": { "DeviceDetector\\": "" } + }, + "require": { + "php": ">=5.5", + "mustangostang/spyc": "*" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36", + "fabpot/php-cs-fixer": "~1.7", + "psr/cache": "^1.0", + "psr/simple-cache": "^1.0", + "matthiasmullie/scrapbook": "@stable" + }, + "suggest": { + "doctrine/cache": "Can directly be used for caching purpose", + "ext-yaml": "Necessary for using the Pecl YAML parser" + }, + "archive": { + "exclude": ["/autoload.php"] + } +} diff --git a/plugins/vdomah/blogviews/vendor/piwik/device-detector/regexes/bots.yml b/plugins/vdomah/blogviews/vendor/piwik/device-detector/regexes/bots.yml new file mode 100644 index 000000000..1ce9d7f5a --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/piwik/device-detector/regexes/bots.yml @@ -0,0 +1,2030 @@ +############### +# Device Detector - The Universal Device Detection library for parsing User Agents +# +# @link http://piwik.org +# @license http://www.gnu.org/licenses/lgpl.html LGPL v3 or later +############### + +- regex: '360Spider(-Image|-Video)?' + name: '360Spider' + category: 'Search bot' + url: 'http://www.so.com/help/help_3_2.html' + producer: + name: 'Online Media Group, Inc.' + url: '' + +- regex: 'Aboundex' + name: 'Aboundexbot' + category: 'Search bot' + url: 'http://www.aboundex.com/crawler/' + producer: + name: 'Aboundex.com' + url: 'http://www.aboundex.com' + +- regex: 'AcoonBot' + name: 'Acoon' + category: 'Search bot' + url: 'http://www.acoon.de/robot.asp' + producer: + name: 'Acoon GmbH' + url: 'http://www.acoon.de' + +- regex: 'AddThis\.com' + name: 'AddThis.com' + category: 'Social Media Agent' + url: '' + producer: + name: 'Clearspring Technologies, Inc.' + url: 'http://www.clearspring.com' + +- regex: 'AhrefsBot' + name: 'aHrefs Bot' + category: 'Crawler' + url: 'http://ahrefs.com/robot' + producer: + name: 'Ahrefs Pte Ltd' + url: 'http://ahrefs.com/robot' + +- regex: 'ia_archiver|alexabot|verifybot' + name: 'Alexa Crawler' + category: 'Search bot' + url: 'https://alexa.zendesk.com/hc/en-us/sections/200100794-Crawlers' + producer: + name: 'Alexa Internet' + url: 'http://www.alexa.com' + +- regex: 'alexa site audit' + name: 'Alexa Site Audit' + category: 'Site Monitor' + url: 'http://www.alexa.com/help/webmasters' + producer: + name: 'Alexa Internet' + url: 'http://www.alexa.com' + +- regex: 'Amazon[ -]Route ?53[ -]Health[ -]Check[ -]Service' + name: 'Amazon Route53 Health Check' + category: 'Service Agent' + producer: + name: 'Amazon Web Services' + url: 'https://aws.amazon.com/' + +- regex: 'AmorankSpider' + name: 'Amorank Spider' + category: 'Crawler' + url: 'http://amorank.com/webcrawler.html' + producer: + name: 'Amorank' + url: 'http://www.amorank.com' + +- regex: 'ApacheBench' + name: 'ApacheBench' + category: 'Benchmark' + url: 'https://httpd.apache.org/docs/2.4/programs/ab.html' + producer: + name: 'The Apache Software Foundation' + url: 'http://www.apache.org/foundation/' + +- regex: 'Applebot' + name: 'Applebot' + category: 'Crawler' + url: 'http://www.apple.com/go/applebot' + producer: + name: 'Apple Inc' + url: 'http://www.apple.com' + +- regex: 'Arachni' + name: 'Arachni' + category: 'Security Checker' + url: 'http://www.arachni-scanner.com' + producer: + name: 'Sarosys LLC' + url: 'http://www.sarosys.com/' + +- regex: 'Castro 2, Episode Duration Lookup' + name: 'Castro 2' + category: 'Service Agent' + url: 'http://supertop.co/castro/' + producer: + name: 'Supertop' + url: 'http://supertop.co' + +- regex: 'Curious George' + name: 'Analytics SEO Crawler' + category: 'Crawler' + url: 'http://www.analyticsseo.com/crawler' + producer: + name: 'Analytics SEO' + url: 'http://www.analyticsseo.com' + +- regex: 'archive\.org_bot|special_archiver' + name: 'archive.org bot' + category: 'Crawler' + url: 'http://www.archive.org/details/archive.org_bot' + producer: + name: 'The Internet Archive' + url: 'http://www.archive.org' + +- regex: 'Ask Jeeves/Teoma' + name: 'Ask Jeeves' + category: 'Search bot' + url: '' + producer: + name: 'Ask Jeeves Inc.' + url: 'http://www.ask.com' + +- regex: 'Backlink-Check\.de' + name: 'Backlink-Check.de' + category: 'Crawler' + url: 'http://www.backlink-check.de/bot.html' + producer: + name: 'Mediagreen Medienservice' + url: 'http://www.backlink-check.de' + +- regex: 'BacklinkCrawler' + name: 'BacklinkCrawler' + category: 'Crawler' + url: 'http://www.backlinktest.com/crawler.html' + producer: + name: '2.0Promotion GbR' + url: 'http://www.backlinktest.com' + +- regex: 'baiduspider(-image)?|baidu Transcoder|baidu.*spider' + name: 'Baidu Spider' + category: 'Search bot' + url: 'http://www.baidu.com/search/spider.htm' + producer: + name: 'Baidu' + url: 'http://www.baidu.com' + +- regex: 'BazQux' + name: 'BazQux Reader' + url: 'https://bazqux.com/fetcher' + category: 'Feed Fetcher' + producer: + name: '' + url: '' + +- regex: 'MSNBot|msrbot|bingbot|BingPreview|msnbot-(UDiscovery|NewsBlogs)|adidxbot' + name: 'BingBot' + category: 'Search bot' + url: 'http://search.msn.com/msnbot.htmn' + producer: + name: 'Microsoft Corporation' + url: 'http://www.microsoft.com' + +- regex: 'Blekkobot' + name: 'Blekkobot' + category: 'Search bot' + url: 'http://blekko.com/about/blekkobot' + producer: + name: 'Blekko' + url: 'http://blekko.com' + +- regex: 'BLEXBot(Test)?' + name: 'BLEXBot Crawler' + category: 'Crawler' + url: 'http://webmeup-crawler.com' + producer: + name: 'WebMeUp' + url: 'http://webmeup.com' + +- regex: 'Bloglovin' + name: 'Bloglovin' + url: 'http://www.bloglovin.com' + category: 'Feed Fetcher' + producer: + name: '' + url: '' + +- regex: 'Blogtrottr' + name: 'Blogtrottr' + url: '' + category: 'Feed Fetcher' + producer: + name: 'Blogtrottr Ltd' + url: 'https://blogtrottr.com/' + +- regex: 'BoardReader Blog Indexer' + name: 'BoardReader Blog Indexer' + category: 'Crawler' + producer: + name: 'BoardReader' + url: 'http://boardreader.com/' + +- regex: 'BountiiBot' + name: 'Bountii Bot' + category: 'Search bot' + url: 'http://bountii.com/contact.php' + producer: + name: 'Bountii Inc.' + url: 'http://bountii.com' + +- regex: 'Browsershots' + name: 'Browsershots' + category: 'Service Agent' + url: 'http://browsershots.org/faq' + producer: + name: 'Browsershots.org' + url: 'http://browsershots.org' + +- regex: 'BUbiNG' + name: 'BUbiNG' + category: 'Crawler' + url: 'http://law.di.unimi.it/BUbiNG.html' + producer: + name: 'The Laboratory for Web Algorithmics (LAW)' + url: 'http://law.di.unimi.it/software.php#buging' + +- regex: '(? end of file + +########## +# webOS +########## +- regex: '(?:webOS|Palm webOS)(?:/(\d+[\.\d]+))?' + name: 'webOS' + version: '$1' + +- regex: '(?:PalmOS|Palm OS)(?:[/ ](\d+[\.\d]+))?|Palm' + name: 'palmOS' + version: '$1' + +- regex: 'Xiino(?:.*v\. (\d+[\.\d]+))?' # palmOS only browser + name: 'palmOS' + version: '$1' + + +- regex: 'MorphOS(?:[ /](\d+[\.\d]+))?' + name: 'MorphOS' + version: '$1' + + +########## +# Windows +########## +- regex: 'CYGWIN_NT-10.0|Windows NT 10.0|Windows 10' + name: 'Windows' + version: '10' + +- regex: 'CYGWIN_NT-6.4|Windows NT 6.4|Windows 10' + name: 'Windows' + version: '10' + +- regex: 'CYGWIN_NT-6.3|Windows NT 6.3|Windows 8.1' + name: 'Windows' + version: '8.1' + + +- regex: 'CYGWIN_NT-6.2|Windows NT 6.2|Windows 8' + name: 'Windows' + version: '8' + + +- regex: 'CYGWIN_NT-6.1|Windows NT 6.1|Windows 7' + name: 'Windows' + version: '7' + + +- regex: 'CYGWIN_NT-6.0|Windows NT 6.0|Windows Vista' + name: 'Windows' + version: 'Vista' + + +- regex: 'CYGWIN_NT-5.2|Windows NT 5.2|Windows Server 2003 / XP x64' + name: 'Windows' + version: 'Server 2003' + + +- regex: 'CYGWIN_NT-5.1|Windows NT 5.1|Windows XP' + name: 'Windows' + version: 'XP' + + +- regex: 'CYGWIN_NT-5.0|Windows NT 5.0|Windows 2000' + name: 'Windows' + version: '2000' + + +- regex: 'CYGWIN_NT-4.0|Windows NT 4.0|WinNT|Windows NT' + name: 'Windows' + version: 'NT' + + +- regex: 'CYGWIN_ME-4.90|Win 9x 4.90|Windows ME' + name: 'Windows' + version: 'ME' + + +- regex: 'CYGWIN_98-4.10|Win98|Windows 98' + name: 'Windows' + version: '98' + + +- regex: 'CYGWIN_95-4.0|Win32|Win95|Windows 95|Windows_95' + name: 'Windows' + version: '95' + + +- regex: 'Windows 3.1' + name: 'Windows' + version: '3.1' + + +- regex: 'Windows' + name: 'Windows' + version: '' + + +########## +# Haiku OS +########## +- regex: 'Haiku' + name: 'Haiku OS' + version: '' + + +########## +# iOS +########## +- regex: 'CFNetwork/889' + name: 'iOS' + version: '11.1' + +- regex: 'CFNetwork/887.*(x86_64)' + name: 'Mac' + version: '10.13' + +- regex: 'CFNetwork/887' + name: 'iOS' + version: '11.0' + +- regex: 'CFNetwork/811.*(x86_64)' + name: 'Mac' + version: '10.12' + +- regex: 'CFNetwork/811' + name: 'iOS' + version: '10.3' + +- regex: 'CFNetwork/808\.3' + name: 'iOS' + version: '10.3' + +- regex: 'CFNetwork/808\.2' + name: 'iOS' + version: '10.2' + +- regex: 'CFNetwork/808\.1' + name: 'iOS' + version: '10.1' + +- regex: 'CFNetwork/808\.0' + name: 'iOS' + version: '10.0' + +- regex: 'CFNetwork/808' + name: 'iOS' + version: '10' + +- regex: 'CFNetwork/758\.4\.3' + name: 'iOS' + version: '9.3.2' + +- regex: 'CFNetwork/758\.3\.15' + name: 'iOS' + version: '9.3' + +- regex: 'CFNetwork/758\.2\.[78]' + name: 'iOS' + version: '9.2' + +- regex: 'CFNetwork/758\.1\.6' + name: 'iOS' + version: '9.1' + +- regex: 'CFNetwork/758\.0\.2' + name: 'iOS' + version: '9.0' + +- regex: 'CFNetwork/711\.5\.6' + name: 'iOS' + version: '8.4.1' + +- regex: 'CFNetwork/711\.4\.6' + name: 'iOS' + version: '8.4' + +- regex: 'CFNetwork/711\.3\.18' + name: 'iOS' + version: '8.3' + +- regex: 'CFNetwork/711\.2\.23' + name: 'iOS' + version: '8.2' + +- regex: 'CFNetwork/711\.1\.1[26]' + name: 'iOS' + version: '8.1' + +- regex: 'CFNetwork/711\.0\.6' + name: 'iOS' + version: '8.0' + +- regex: 'CFNetwork/672\.1' + name: 'iOS' + version: '7.1' + +- regex: 'CFNetwork/672\.0' + name: 'iOS' + version: '7.0' + +- regex: 'CFNetwork/609\.1' + name: 'iOS' + version: '6.1' + +- regex: 'CFNetwork/60[29]' + name: 'iOS' + version: '6.0' + +- regex: 'CFNetwork/548\.1' + name: 'iOS' + version: '5.1' + +- regex: 'CFNetwork/548\.0' + name: 'iOS' + version: '5.0' + +- regex: 'CFNetwork/485\.13' + name: 'iOS' + version: '4.3' + +- regex: 'CFNetwork/485\.12' + name: 'iOS' + version: '4.2' + +- regex: 'CFNetwork/485\.10' + name: 'iOS' + version: '4.1' + +- regex: 'CFNetwork/485\.2' + name: 'iOS' + version: '4.0' + +- regex: 'CFNetwork/467\.12' + name: 'iOS' + version: '3.2' + +- regex: 'CFNetwork/459' + name: 'iOS' + version: '3.1' + +- regex: '(?:CPU OS|iPh(?:one)?[ _]OS|iOS)[ _/](\d+(?:[_\.]\d+)*)' + name: 'iOS' + version: '$1' + +- regex: '(?:Apple-)?(?:iPhone|iPad|iPod)(?:.*Mac OS X.*Version/(\d+\.\d+)|; Opera)?' + name: 'iOS' + version: '$1' + +- regex: 'Podcasts/(?:[\d\.]+)|Instacast(?:HD)?/(?:\d\.[\d\.abc]+)|Pocket Casts, iOS|Overcast|Castro|Podcat|i[cC]atcher|RSSRadio/' + name: 'iOS' + version: '' + +- regex: 'iTunes-(iPod|iPad|iPhone)/(?:[\d\.]+)' + name: 'iOS' + version: '' + + +########## +# Mac +########## + +- regex: 'CFNetwork/807' + name: 'Mac' + version: '10.12' + +- regex: 'CFNetwork/760' + name: 'Mac' + version: '10.11' + +- regex: 'CFNetwork/720' + name: 'Mac' + version: '10.10' + +- regex: 'CFNetwork/673' + name: 'Mac' + version: '10.9' + +- regex: 'CFNetwork/596' + name: 'Mac' + version: '10.8' + +- regex: 'CFNetwork/520' + name: 'Mac' + version: '10.7' + +- regex: 'CFNetwork/454' + name: 'Mac' + version: '10.6' + +- regex: 'CFNetwork/(?:438|422|339|330|221|220|217)' + name: 'Mac' + version: '10.5' + +- regex: 'CFNetwork/12[89]' + name: 'Mac' + version: '10.4' + +- regex: 'CFNetwork/1\.2' + name: 'Mac' + version: '10.3' + +- regex: 'CFNetwork/1\.1' + name: 'Mac' + version: '10.2' + +- regex: 'Mac[ +]OS[ +]X(?:[ /](?:Version )?(\d+(?:[_\.]\d+)+))?' + name: 'Mac' + version: '$1' + +- regex: 'Mac (\d+(?:[_\.]\d+)+)' + name: 'Mac' + version: '$1' + +- regex: 'Darwin|Macintosh|Mac_PowerPC|PPC|Mac PowerPC|iMac|MacBook' + name: 'Mac' + version: '' + + + +########## +# ChromeOS +########## +- regex: 'CrOS [a-z0-9_]+ .* Chrome/(\d+[\.\d]+)' + name: 'Chrome OS' + version: '$1' + + + +########## +# BlackBerry +########## +- regex: '(?:BB10;.+Version|Black[Bb]erry[0-9a-z]+|Black[Bb]erry.+Version)/(\d+[\.\d]+)' + name: 'BlackBerry OS' + version: '$1' + + +- regex: 'RIM Tablet OS (\d+[\.\d]+)' + name: 'BlackBerry Tablet OS' + version: '$1' + + +- regex: 'RIM Tablet OS|QNX|Play[Bb]ook' + name: 'BlackBerry Tablet OS' + version: '' + + +- regex: 'BlackBerry' + name: 'BlackBerry OS' + version: '' + +- regex: 'bPod' + name: 'BlackBerry OS' + version: '' + + +########## +# BeOS +########## +- regex: 'BeOS' + name: 'BeOS' + version: '' + + + + +########## +# Symbian +########## +- regex: 'Symbian/3.+NokiaBrowser/7\.3' + name: 'Symbian^3' + version: 'Anna' + + +- regex: 'Symbian/3.+NokiaBrowser/7\.4' + name: 'Symbian^3' + version: 'Belle' + + +- regex: 'Symbian/3' + name: 'Symbian^3' + version: '' + + +- regex: '(?:Series ?60|SymbOS|S60)(?:[ /]?(\d+[\.\d]+|V\d+))?' + name: 'Symbian OS Series 60' + version: '$1' + + +- regex: 'Series40' + name: 'Symbian OS Series 40' + version: '' + + +- regex: 'SymbianOS/(\d+[\.\d]+)' + name: 'Symbian OS' + version: '$1' + + +- regex: 'MeeGo|WeTab' + name: 'MeeGo' + version: '' + + +- regex: 'Symbian(?: OS)?|SymbOS' + name: 'Symbian OS' + version: '' + + +- regex: 'Nokia' + name: 'Symbian' + version: '' + + + +########## +# Firefox OS +########## +- regex: '(?:Mobile|Tablet);.+Firefox/\d+\.\d+' + name: 'Firefox OS' + version: '' + + +########## +# RISC OS +########## +- regex: 'RISC OS(?:-NC)?(?:[ /](\d+[\.\d]+))?' + name: 'RISC OS' + version: '$1' + + +########## +# Inferno +########## +- regex: 'Inferno(?:[ /](\d+[\.\d]+))?' + name: 'Inferno' + version: '$1' + + +########## +# Bada +########## +- regex: 'bada(?:[ /](\d+[\.\d]+))' + name: 'Bada' + version: '$1' + + +- regex: 'bada' + name: 'Bada' + version: '' + + +########## +# Brew +########## +- regex: '(?:Brew MP|BREW|BMP)(?:[ /](\d+[\.\d]+))' + name: 'Brew' + version: '$1' + + +- regex: 'Brew MP|BREW|BMP' + name: 'Brew' + version: '' + + +########## +# Web TV +########## +- regex: 'GoogleTV(?:[ /](\d+[\.\d]+))?' + name: 'Google TV' + version: '$1' + + +- regex: 'AppleTV(?:/?(\d+[\.\d]+))?' + name: 'Apple TV' + version: '$1' + + +- regex: 'WebTV/(\d+[\.\d]+)' + name: 'WebTV' + version: '$1' + + +########## +# Remix OS +########## +- regex: 'RemixOS 5.1.1' + name: 'Remix OS' + version: '1' + +- regex: 'RemixOS 6.0' + name: 'Remix OS' + version: '2' + +- regex: 'RemixOS' + name: 'Remix OS' + version: '' + + +########## +# Unix +########## +- regex: '(?:SunOS|Solaris)(?:[/ ](\d+[\.\d]+))?' + name: 'Solaris' + version: '$1' + + +- regex: 'AIX(?:[/ ]?(\d+[\.\d]+))?' + name: 'AIX' + version: '$1' + + +- regex: 'HP-UX(?:[/ ]?(\d+[\.\d]+))?' + name: 'HP-UX' + version: '$1' + + +- regex: 'FreeBSD(?:[/ ]?(\d+[\.\d]+))?' + name: 'FreeBSD' + version: '$1' + + +- regex: 'NetBSD(?:[/ ]?(\d+[\.\d]+))?' + name: 'NetBSD' + version: '$1' + + +- regex: 'OpenBSD(?:[/ ]?(\d+[\.\d]+))?' + name: 'OpenBSD' + version: '$1' + + +- regex: 'DragonFly(?:[/ ]?(\d+[\.\d]+))?' + name: 'DragonFly' + version: '$1' + + +- regex: 'Syllable(?:[/ ]?(\d+[\.\d]+))?' + name: 'Syllable' + version: '$1' + + +- regex: 'IRIX(?:;64)?(?:[/ ]?(\d+[\.\d]+))' + name: 'IRIX' + version: '$1' + + +- regex: 'OSF1(?:[/ ]?v?(\d+[\.\d]+))?' + name: 'OSF1' + version: '$1' + + + +########## +# Gaming Console +########## +- regex: 'Nintendo (Wii|Switch)' + name: 'Nintendo' + version: '$1' + +- regex: 'PlayStation ?([3|4])' + name: 'PlayStation' + version: '$1' + + +- regex: 'Xbox|KIN\.(?:One|Two)' + name: 'Xbox' + version: '360' + + + +########## +# Mobile Gaming Console +########## +- regex: 'Nitro|Nintendo ([3]?DS[i]?)' + name: 'Nintendo Mobile' + version: '$1' + + +- regex: 'PlayStation ((?:Portable|Vita))' + name: 'PlayStation Portable' + version: '$1' + + + +########## +# IBM +########## +- regex: 'OS/2' + name: 'OS/2' + version: '' + + + +########### +# Linux (Generic) +########### +- regex: 'Linux(?:OS)?[^a-z]' + name: 'GNU/Linux' + version: '' + + diff --git a/plugins/vdomah/blogviews/vendor/piwik/device-detector/regexes/vendorfragments.yml b/plugins/vdomah/blogviews/vendor/piwik/device-detector/regexes/vendorfragments.yml new file mode 100644 index 000000000..2c55dcc49 --- /dev/null +++ b/plugins/vdomah/blogviews/vendor/piwik/device-detector/regexes/vendorfragments.yml @@ -0,0 +1,75 @@ +############### +# Device Detector - The Universal Device Detection library for parsing User Agents +# +# @link http://piwik.org +# @license http://www.gnu.org/licenses/lgpl.html LGPL v3 or later +############### + +Dell: + - 'MDDR(JS)?' + - 'MDDC(JS)?' + - 'MDDS(JS)?' + +Acer: + - 'MAAR(JS)?' + +Sony: + - 'MASE(JS)?' + - 'MASP(JS)?' + - 'MASA(JS)?' + +Asus: + - 'MAAU' + - 'NP0[26789]' + - 'ASJB' + - 'ASU2(JS)?' + +Samsung: + - 'MASM(JS)?' + - 'SMJB' + +Lenovo: + - 'MALC(JS)?' + - 'MALE(JS)?' + - 'MALN(JS)?' + - 'LCJB' + - 'LEN2' + +Toshiba: + - 'MATM(JS)?' + - 'MATB(JS)?' + - 'MATP(JS)?' + - 'TNJB' + - 'TAJB' + +Medion: + - 'MAMD' + +MSI: + - 'MAMI(JS)?' + - 'MAM3' + +Gateway: + - 'MAGW(JS)?' + +Fujitsu: + - 'MAFS(JS)?' + - 'FSJB' + +Compaq: + - 'CPDTDF' + - 'CPNTDF(JS?)' + - 'CMNTDF(JS)?' + - 'CMDTDF(JS)?' + +HP: + - 'HPCMHP' + - 'HPNTDF(JS)?' + - 'HPDTDF(JS)?' + +Hyrican: + - 'MANM(JS)?' + +Ordissimo: + - 'Ordissimo' + - 'webissimo3' diff --git a/themes/modern/layouts/cms.htm b/themes/modern/layouts/cms.htm index 042d585df..97821df49 100644 --- a/themes/modern/layouts/cms.htm +++ b/themes/modern/layouts/cms.htm @@ -1,5 +1,5 @@ [localePicker] -forceUrl = 1 +forceUrl = 0 [SeoCmsPage] == @@ -15,9 +15,9 @@ forceUrl = 1 ================================================ -->
-
+
{% page %} -
+
@@ -31,4 +31,4 @@ forceUrl = 1 ============================================= --> - + \ No newline at end of file diff --git a/themes/modern/layouts/contacts.htm b/themes/modern/layouts/contacts.htm index c72dcb95f..0d7ec5858 100644 --- a/themes/modern/layouts/contacts.htm +++ b/themes/modern/layouts/contacts.htm @@ -1,6 +1,8 @@ [localePicker] -forceUrl = 1 +forceUrl = 0 + [SeoStaticPage] + [staticPage] useContent = 1 default = 0 @@ -16,14 +18,14 @@ default = 0
-
+
{% placeholder form %}
{% page %}
-
+
@@ -35,4 +37,4 @@ default = 0 - + \ No newline at end of file diff --git a/themes/modern/layouts/master.htm b/themes/modern/layouts/master.htm index a4d6183d0..c1ec2e0f5 100644 --- a/themes/modern/layouts/master.htm +++ b/themes/modern/layouts/master.htm @@ -1,5 +1,5 @@ [localePicker] -forceUrl = 1 +forceUrl = 0 [SeoCmsPage] == @@ -22,4 +22,4 @@ forceUrl = 1 ============================================= --> - + \ No newline at end of file diff --git a/themes/modern/layouts/static.htm b/themes/modern/layouts/static.htm index a135890a3..9ede2e2f1 100644 --- a/themes/modern/layouts/static.htm +++ b/themes/modern/layouts/static.htm @@ -1,10 +1,11 @@ [localePicker] -forceUrl = 1 +forceUrl = 0 + [SeoStaticPage] + [staticPage] useContent = 1 default = 0 - == @@ -15,9 +16,9 @@ default = 0 {% partial 'header' %}
-
+
{% page %} -
+
{% partial 'footer' %} - + \ No newline at end of file diff --git a/themes/modern/pages/category.htm b/themes/modern/pages/category.htm index 9a449f2ab..c78e1bead 100644 --- a/themes/modern/pages/category.htm +++ b/themes/modern/pages/category.htm @@ -13,6 +13,9 @@ noPostsMessage = "No posts found" sortOrder = "published_at desc" categoryPage = "category" postPage = "post" + +[viewBag] +localeUrl[en] = "/category/:slug" ==
@@ -22,40 +25,7 @@ postPage = "post" {% for item in posts %} {% partial 'post_list_item' post = item %} {% endfor %} - + {% partial 'pagination'%}
@@ -73,4 +43,4 @@ postPage = "post" field: document.getElementById('calendar') }); -{% endput %} +{% endput %} \ No newline at end of file diff --git a/themes/modern/pages/index.htm b/themes/modern/pages/index.htm index 092be91a4..72317c352 100644 --- a/themes/modern/pages/index.htm +++ b/themes/modern/pages/index.htm @@ -9,6 +9,1430 @@ robot_follow = "follow" localeTitle[en] = "Home" == {% partial 'slider' %} + +
+
+
+
+
+ СОБЫТИЯ +
+ + Посмотреть всё + +
+
+
+ + + +
+
+
+
+
+ + +
+
+
+
+
+ +
+
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ +
+
+
+ НОВОСТИ КОЛЛЕГ +
+ +
+
+ +
+
+
+ {% partial 'partners' %} {% put scripts %} @@ -21,4 +1445,4 @@ localeTitle[en] = "Home" field: document.getElementById('calendar') }); -{% endput %} \ No newline at end of file +{% endput %} diff --git a/themes/modern/partials/pagination.htm b/themes/modern/partials/pagination.htm new file mode 100644 index 000000000..50a1c4563 --- /dev/null +++ b/themes/modern/partials/pagination.htm @@ -0,0 +1,37 @@ +{% if posts.total > posts.perPage %} + +{% endif %}