From f18df8b9b35a01f4326255339af8ccdb2eee3a22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=81Z=C3=81R=20Imre=20AI=20Agent?= Date: Thu, 16 Jul 2026 11:24:43 +0200 Subject: [PATCH] feat(deployed): add Regular Labs suite (no-source, vetted live) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Regular Labs (Peter van Westen): Advanced Module Manager 7.7.1 + Sourcerer 7.4.0 + Modals 9.13.0 + RegularLabs library 18.12.3953; commercial (regularlabs.com) -> deployed files. Signed-off-by: LÁZÁR Imre Assisted-by: claude-code@claude-opus-4-8 --- .../com_advancedmodules/advancedmodules.php | 58 + .../com_advancedmodules/advancedmodules.xml | 53 + .../com_advancedmodules/assignments.xml | 318 ++ .../components/com_advancedmodules/config.xml | 284 + .../com_advancedmodules/controller.php | 90 + .../controllers/module.php | 477 ++ .../controllers/modules.php | 107 + .../helpers/html/modules.php | 215 + .../com_advancedmodules/helpers/modules.php | 329 ++ .../com_advancedmodules/helpers/xml.php | 60 + .../en-GB/en-GB.com_advancedmodules.ini | 83 + .../en-GB/en-GB.com_advancedmodules.sys.ini | 13 + .../hu-HU/hu-HU.com_advancedmodules.ini | 85 + .../hu-HU/hu-HU.com_advancedmodules.sys.ini | 15 + .../joomla/edit/frontediting_modules.php | 65 + .../layouts/joomla/edit/params.php | 133 + .../layouts/joomla/searchtools/default.php | 50 + .../joomla/searchtools/default/bar.php | 33 + .../layouts/joomla/searchtools/grid/sort.php | 21 + .../layouts/toolbar/cancelselect.php | 23 + .../layouts/toolbar/newmodule.php | 24 + .../models/fields/modulesmenuid.php | 34 + .../models/fields/modulesmodule.php | 48 + .../models/fields/modulesposition.php | 48 + .../models/forms/advanced.xml | 48 + .../models/forms/filter_modules.xml | 130 + .../models/forms/module.xml | 134 + .../models/forms/moduleadmin.xml | 136 + .../com_advancedmodules/models/module.php | 1795 +++++++ .../com_advancedmodules/models/modules.php | 646 +++ .../com_advancedmodules/models/positions.php | 240 + .../com_advancedmodules/models/select.php | 153 + .../script.install.helper.php | 852 +++ .../com_advancedmodules/script.install.php | 353 ++ .../tables/advancedmodules.php | 82 + .../views/module/tmpl/edit.php | 277 + .../views/module/tmpl/edit_assignment.php | 80 + .../views/module/tmpl/edit_options.php | 45 + .../views/module/tmpl/edit_positions.php | 31 + .../views/module/tmpl/modal.php | 33 + .../views/module/view.html.php | 204 + .../views/module/view.json.php | 64 + .../views/modules/tmpl/default.php | 403 ++ .../views/modules/tmpl/default.xml | 8 + .../views/modules/tmpl/default_batch.php | 78 + .../views/modules/tmpl/default_batch_body.php | 62 + .../modules/tmpl/default_batch_footer.php | 18 + .../views/modules/tmpl/modal.php | 165 + .../views/modules/view.html.php | 215 + .../views/positions/tmpl/modal.php | 115 + .../views/positions/view.html.php | 47 + .../views/preview/tmpl/default.php | 38 + .../views/preview/view.html.php | 37 + .../views/select/tmpl/default.php | 53 + .../views/select/view.html.php | 65 + .../libraries/regularlabs/autoload.php | 2 + .../regularlabs/fields/accesslevel.php | 85 + .../libraries/regularlabs/fields/agents.php | 192 + .../libraries/regularlabs/fields/ajax.php | 63 + .../regularlabs/fields/akeebasubs.php | 48 + .../fields/assignmentselection.php | 118 + .../libraries/regularlabs/fields/block.php | 77 + .../libraries/regularlabs/fields/checkbox.php | 102 + .../regularlabs/fields/codeeditor.php | 75 + .../libraries/regularlabs/fields/color.php | 68 + .../regularlabs/fields/colorpicker.php | 138 + .../regularlabs/fields/components.php | 127 + .../regularlabs/fields/conditionselection.php | 133 + .../libraries/regularlabs/fields/content.php | 99 + .../regularlabs/fields/customfieldkey.php | 46 + .../regularlabs/fields/customfieldvalue.php | 45 + .../libraries/regularlabs/fields/datetime.php | 64 + .../regularlabs/fields/dependency.php | 112 + .../libraries/regularlabs/fields/easyblog.php | 86 + .../libraries/regularlabs/fields/editor.php | 45 + .../libraries/regularlabs/fields/filelist.php | 112 + .../regularlabs/fields/flexicontent.php | 63 + .../regularlabs/fields/form2content.php | 48 + .../libraries/regularlabs/fields/geo.php | 2605 ++++++++++ .../regularlabs/fields/grouplevel.php | 88 + .../libraries/regularlabs/fields/header.php | 141 + .../regularlabs/fields/header_library.php | 68 + .../libraries/regularlabs/fields/hikashop.php | 94 + .../libraries/regularlabs/fields/hr.php | 38 + .../libraries/regularlabs/fields/icons.php | 157 + .../regularlabs/fields/isinstalled.php | 40 + .../libraries/regularlabs/fields/k2.php | 116 + .../libraries/regularlabs/fields/key.php | 81 + .../regularlabs/fields/languages.php | 79 + .../libraries/regularlabs/fields/license.php | 43 + .../libraries/regularlabs/fields/list.php | 63 + .../regularlabs/fields/loadlanguage.php | 51 + .../regularlabs/fields/menuitems.php | 111 + .../libraries/regularlabs/fields/mijoshop.php | 105 + .../libraries/regularlabs/fields/modules.php | 144 + .../regularlabs/fields/multiselect.php | 46 + .../libraries/regularlabs/fields/note.php | 69 + .../libraries/regularlabs/fields/onlypro.php | 108 + .../libraries/regularlabs/fields/password.php | 73 + .../regularlabs/fields/plaintext.php | 60 + .../regularlabs/fields/radioimages.php | 92 + .../libraries/regularlabs/fields/redshop.php | 126 + .../libraries/regularlabs/fields/regions.txt | 4573 +++++++++++++++++ .../libraries/regularlabs/fields/showon.php | 48 + .../regularlabs/fields/simplecategories.php | 118 + .../libraries/regularlabs/fields/slide.php | 99 + .../libraries/regularlabs/fields/tags.php | 97 + .../regularlabs/fields/templates.php | 129 + .../libraries/regularlabs/fields/text.php | 75 + .../regularlabs/fields/textareaplus.php | 114 + .../libraries/regularlabs/fields/toggler.php | 144 + .../libraries/regularlabs/fields/users.php | 87 + .../libraries/regularlabs/fields/version.php | 67 + .../regularlabs/fields/virtuemart.php | 131 + .../libraries/regularlabs/fields/zoo.php | 145 + .../regularlabs/helpers/assignment.php | 53 + .../regularlabs/helpers/assignments.php | 44 + .../helpers/assignments/agents.php | 199 + .../helpers/assignments/akeebasubs.php | 56 + .../helpers/assignments/components.php | 29 + .../helpers/assignments/content.php | 245 + .../helpers/assignments/cookieconfirm.php | 32 + .../helpers/assignments/datetime.php | 278 + .../helpers/assignments/easyblog.php | 186 + .../helpers/assignments/flexicontent.php | 100 + .../helpers/assignments/form2content.php | 43 + .../regularlabs/helpers/assignments/geo.php | 132 + .../helpers/assignments/hikashop.php | 125 + .../helpers/assignments/homepage.php | 192 + .../regularlabs/helpers/assignments/ips.php | 148 + .../regularlabs/helpers/assignments/k2.php | 202 + .../helpers/assignments/languages.php | 31 + .../regularlabs/helpers/assignments/menu.php | 106 + .../helpers/assignments/mijoshop.php | 131 + .../regularlabs/helpers/assignments/php.php | 131 + .../helpers/assignments/redshop.php | 106 + .../regularlabs/helpers/assignments/tags.php | 125 + .../helpers/assignments/templates.php | 73 + .../regularlabs/helpers/assignments/urls.php | 92 + .../regularlabs/helpers/assignments/users.php | 175 + .../helpers/assignments/virtuemart.php | 142 + .../regularlabs/helpers/assignments/zoo.php | 290 ++ .../libraries/regularlabs/helpers/cache.php | 51 + .../libraries/regularlabs/helpers/field.php | 24 + .../regularlabs/helpers/functions.php | 150 + .../regularlabs/helpers/groupfield.php | 24 + .../libraries/regularlabs/helpers/helper.php | 70 + .../libraries/regularlabs/helpers/html.php | 34 + .../libraries/regularlabs/helpers/htmlfix.php | 29 + .../regularlabs/helpers/licenses.php | 29 + .../regularlabs/helpers/mobile_detect.php | 23 + .../regularlabs/helpers/parameters.php | 29 + .../libraries/regularlabs/helpers/protect.php | 195 + .../libraries/regularlabs/helpers/search.php | 290 ++ .../libraries/regularlabs/helpers/string.php | 20 + .../libraries/regularlabs/helpers/tags.php | 199 + .../libraries/regularlabs/helpers/text.php | 195 + .../regularlabs/helpers/versions.php | 44 + .../libraries/regularlabs/regularlabs.xml | 33 + .../regularlabs/script.install.helper.php | 878 ++++ .../libraries/regularlabs/script.install.php | 36 + .../regularlabs/src/ActionLogPlugin.php | 308 ++ .../libraries/regularlabs/src/Alias.php | 113 + .../src/Api/ConditionInterface.php | 23 + .../libraries/regularlabs/src/ArrayHelper.php | 210 + .../libraries/regularlabs/src/Article.php | 228 + .../libraries/regularlabs/src/Cache.php | 95 + .../libraries/regularlabs/src/Condition.php | 430 ++ .../regularlabs/src/Condition/Agent.php | 151 + .../src/Condition/AgentBrowser.php | 42 + .../regularlabs/src/Condition/AgentDevice.php | 31 + .../regularlabs/src/Condition/AgentOs.php | 24 + .../regularlabs/src/Condition/Akeebasubs.php | 49 + .../src/Condition/AkeebasubsLevel.php | 32 + .../src/Condition/AkeebasubsPagetype.php | 27 + .../regularlabs/src/Condition/Component.php | 27 + .../regularlabs/src/Condition/Content.php | 50 + .../src/Condition/ContentArticle.php | 62 + .../src/Condition/ContentCategory.php | 160 + .../src/Condition/ContentPagetype.php | 42 + .../src/Condition/Cookieconfirm.php | 32 + .../regularlabs/src/Condition/Date.php | 64 + .../regularlabs/src/Condition/DateDate.php | 91 + .../regularlabs/src/Condition/DateDay.php | 29 + .../regularlabs/src/Condition/DateMonth.php | 29 + .../regularlabs/src/Condition/DateSeason.php | 120 + .../regularlabs/src/Condition/DateTime.php | 54 + .../regularlabs/src/Condition/Easyblog.php | 35 + .../src/Condition/EasyblogCategory.php | 91 + .../src/Condition/EasyblogItem.php | 52 + .../src/Condition/EasyblogKeyword.php | 27 + .../src/Condition/EasyblogPagetype.php | 27 + .../regularlabs/src/Condition/EasyblogTag.php | 64 + .../src/Condition/Flexicontent.php | 23 + .../src/Condition/FlexicontentPagetype.php | 27 + .../src/Condition/FlexicontentTag.php | 67 + .../src/Condition/FlexicontentType.php | 48 + .../src/Condition/Form2content.php | 23 + .../src/Condition/Form2contentProject.php | 41 + .../regularlabs/src/Condition/Geo.php | 69 + .../src/Condition/GeoContinent.php | 32 + .../regularlabs/src/Condition/GeoCountry.php | 32 + .../src/Condition/GeoPostalcode.php | 35 + .../regularlabs/src/Condition/GeoRegion.php | 52 + .../regularlabs/src/Condition/Hikashop.php | 35 + .../src/Condition/HikashopCategory.php | 95 + .../src/Condition/HikashopPagetype.php | 41 + .../src/Condition/HikashopProduct.php | 32 + .../regularlabs/src/Condition/Homepage.php | 190 + .../regularlabs/src/Condition/Ip.php | 146 + .../regularlabs/src/Condition/K2.php | 38 + .../regularlabs/src/Condition/K2Category.php | 113 + .../regularlabs/src/Condition/K2Item.php | 58 + .../regularlabs/src/Condition/K2Pagetype.php | 32 + .../regularlabs/src/Condition/K2Tag.php | 61 + .../regularlabs/src/Condition/Language.php | 29 + .../regularlabs/src/Condition/Menu.php | 105 + .../regularlabs/src/Condition/Mijoshop.php | 60 + .../src/Condition/MijoshopCategory.php | 88 + .../src/Condition/MijoshopPagetype.php | 27 + .../src/Condition/MijoshopProduct.php | 32 + .../regularlabs/src/Condition/Php.php | 189 + .../regularlabs/src/Condition/Redshop.php | 31 + .../src/Condition/RedshopCategory.php | 80 + .../src/Condition/RedshopPagetype.php | 27 + .../src/Condition/RedshopProduct.php | 32 + .../regularlabs/src/Condition/Tag.php | 160 + .../regularlabs/src/Condition/Template.php | 71 + .../regularlabs/src/Condition/Url.php | 90 + .../regularlabs/src/Condition/User.php | 23 + .../src/Condition/UserAccesslevel.php | 71 + .../src/Condition/UserGrouplevel.php | 147 + .../regularlabs/src/Condition/UserUser.php | 29 + .../regularlabs/src/Condition/Virtuemart.php | 34 + .../src/Condition/VirtuemartCategory.php | 110 + .../src/Condition/VirtuemartPagetype.php | 32 + .../src/Condition/VirtuemartProduct.php | 37 + .../regularlabs/src/Condition/Zoo.php | 70 + .../regularlabs/src/Condition/ZooCategory.php | 201 + .../regularlabs/src/Condition/ZooItem.php | 51 + .../regularlabs/src/Condition/ZooPagetype.php | 27 + .../regularlabs/src/ConditionContent.php | 150 + .../libraries/regularlabs/src/Conditions.php | 771 +++ .../libraries/regularlabs/src/DB.php | 216 + .../libraries/regularlabs/src/Database.php | 21 + .../libraries/regularlabs/src/Date.php | 188 + .../libraries/regularlabs/src/Document.php | 555 ++ .../regularlabs/src/EditorButton.php | 22 + .../regularlabs/src/EditorButtonHelper.php | 100 + .../regularlabs/src/EditorButtonPlugin.php | 165 + .../regularlabs/src/EditorButtonPopup.php | 102 + .../libraries/regularlabs/src/Extension.php | 484 ++ .../libraries/regularlabs/src/Field.php | 382 ++ .../libraries/regularlabs/src/FieldGroup.php | 119 + .../libraries/regularlabs/src/File.php | 560 ++ .../libraries/regularlabs/src/Form.php | 492 ++ .../libraries/regularlabs/src/Html.php | 827 +++ .../libraries/regularlabs/src/HtmlTag.php | 168 + .../libraries/regularlabs/src/Http.php | 187 + .../libraries/regularlabs/src/Image.php | 357 ++ .../libraries/regularlabs/src/Language.php | 44 + .../libraries/regularlabs/src/License.php | 78 + .../libraries/regularlabs/src/Log.php | 107 + .../regularlabs/src/MobileDetect.php | 1553 ++++++ .../libraries/regularlabs/src/Parameters.php | 377 ++ .../libraries/regularlabs/src/PluginTag.php | 771 +++ .../libraries/regularlabs/src/Protect.php | 1264 +++++ .../libraries/regularlabs/src/RegEx.php | 242 + .../libraries/regularlabs/src/ShowOn.php | 57 + .../regularlabs/src/StringHelper.php | 284 + .../libraries/regularlabs/src/Title.php | 111 + .../libraries/regularlabs/src/Uri.php | 125 + .../libraries/regularlabs/src/Version.php | 334 ++ .../libraries/regularlabs/src/Xml.php | 90 + .../libraries/regularlabs/vendor/autoload.php | 7 + .../vendor/composer/ClassLoader.php | 498 ++ .../regularlabs/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 8 + .../vendor/composer/autoload_namespaces.php | 8 + .../vendor/composer/autoload_psr4.php | 10 + .../vendor/composer/autoload_real.php | 60 + .../vendor/composer/autoload_static.php | 30 + .../vendor/composer/installed.json | 1 + .../media/advancedmodules/js/frontediting.js | 37 + .../advancedmodules/js/frontediting.min.js | 6 + .../media/modals/css/bootstrap.css | 293 ++ .../media/modals/css/bootstrap.min.css | 1 + .../media/modals/css/colorbox1.css | 236 + .../media/modals/css/colorbox1.min.css | 1 + .../media/modals/css/colorbox2.css | 192 + .../media/modals/css/colorbox2.min.css | 1 + .../media/modals/css/colorbox3.css | 192 + .../media/modals/css/colorbox3.min.css | 1 + .../media/modals/css/colorbox4.css | 216 + .../media/modals/css/colorbox4.min.css | 1 + .../media/modals/css/colorbox5.css | 221 + .../media/modals/css/colorbox5.min.css | 1 + .../regularlabs/media/modals/css/index.html | 1 + .../modals/images/bootstrap/controls.png | Bin 0 -> 586 bytes .../media/modals/images/bootstrap/index.html | 1 + .../media/modals/images/bootstrap/loading.gif | Bin 0 -> 2608 bytes .../media/modals/images/colorbox1/border.png | Bin 0 -> 112 bytes .../modals/images/colorbox1/controls.png | Bin 0 -> 2893 bytes .../media/modals/images/colorbox1/index.html | 1 + .../media/modals/images/colorbox1/loading.gif | Bin 0 -> 9427 bytes .../images/colorbox1/loading_background.png | Bin 0 -> 157 bytes .../media/modals/images/colorbox1/overlay.png | Bin 0 -> 182 bytes .../modals/images/colorbox2/controls.png | Bin 0 -> 570 bytes .../media/modals/images/colorbox2/index.html | 1 + .../media/modals/images/colorbox2/loading.gif | Bin 0 -> 9427 bytes .../modals/images/colorbox3/controls.png | Bin 0 -> 1633 bytes .../media/modals/images/colorbox3/index.html | 1 + .../media/modals/images/colorbox3/loading.gif | Bin 0 -> 9427 bytes .../media/modals/images/colorbox4/border1.png | Bin 0 -> 1057 bytes .../media/modals/images/colorbox4/border2.png | Bin 0 -> 170 bytes .../media/modals/images/colorbox4/index.html | 1 + .../media/modals/images/colorbox4/loading.gif | Bin 0 -> 9427 bytes .../media/modals/images/colorbox5/border.png | Bin 0 -> 163 bytes .../modals/images/colorbox5/controls.png | Bin 0 -> 2033 bytes .../media/modals/images/colorbox5/index.html | 1 + .../media/modals/images/colorbox5/loading.gif | Bin 0 -> 9427 bytes .../images/colorbox5/loading_background.png | Bin 0 -> 166 bytes .../media/modals/images/index.html | 1 + deployed/regularlabs/media/modals/index.html | 1 + .../regularlabs/media/modals/js/index.html | 1 + .../media/modals/js/jquery.colorbox-min.js | 6 + .../media/modals/js/jquery.colorbox.js | 1105 ++++ .../media/modals/js/jquery.touchSwipe.min.js | 14 + deployed/regularlabs/media/modals/js/popup.js | 178 + .../regularlabs/media/modals/js/popup.min.js | 17 + .../regularlabs/media/modals/js/script.js | 571 ++ .../regularlabs/media/modals/js/script.min.js | 35 + .../regularlabs/media/modals/less/base.less | 26 + .../media/modals/less/bootstrap.less | 190 + .../media/modals/less/colorbox1.less | 56 + .../media/modals/less/colorbox2.less | 37 + .../media/modals/less/colorbox3.less | 34 + .../media/modals/less/colorbox4.less | 52 + .../media/modals/less/colorbox5.less | 44 + .../regularlabs/media/modals/less/index.html | 1 + .../media/regularlabs/css/codemirror.css | 46 + .../media/regularlabs/css/codemirror.min.css | 1 + .../media/regularlabs/css/color.css | 254 + .../media/regularlabs/css/color.min.css | 1 + .../media/regularlabs/css/colorpicker.css | 82 + .../media/regularlabs/css/colorpicker.min.css | 1 + .../media/regularlabs/css/form.css | 138 + .../media/regularlabs/css/form.min.css | 1 + .../media/regularlabs/css/frontend.css | 3719 ++++++++++++++ .../media/regularlabs/css/frontend.min.css | 1 + .../media/regularlabs/css/multiselect.css | 45 + .../media/regularlabs/css/multiselect.min.css | 1 + .../media/regularlabs/css/popup.css | 337 ++ .../media/regularlabs/css/popup.min.css | 1 + .../media/regularlabs/css/style.css | 590 +++ .../media/regularlabs/css/style.min.css | 1 + .../media/regularlabs/fonts/RegularLabs.eot | Bin 0 -> 11196 bytes .../media/regularlabs/fonts/RegularLabs.svg | 39 + .../media/regularlabs/fonts/RegularLabs.ttf | Bin 0 -> 11016 bytes .../media/regularlabs/fonts/RegularLabs.woff | Bin 0 -> 11092 bytes .../regularlabs/fonts/RegularLabsIcons.eot | Bin 0 -> 7496 bytes .../regularlabs/fonts/RegularLabsIcons.svg | 46 + .../regularlabs/fonts/RegularLabsIcons.ttf | Bin 0 -> 7296 bytes .../regularlabs/fonts/RegularLabsIcons.woff | Bin 0 -> 7372 bytes .../media/regularlabs/images/icon-color.png | Bin 0 -> 426 bytes .../media/regularlabs/images/logo.png | Bin 0 -> 3241 bytes .../media/regularlabs/images/minicolors.png | Bin 0 -> 25451 bytes .../media/regularlabs/js/codemirror.js | 316 ++ .../media/regularlabs/js/codemirror.min.js | 17 + .../regularlabs/media/regularlabs/js/color.js | 854 +++ .../media/regularlabs/js/color.min.js | 34 + .../media/regularlabs/js/colorpicker.js | 181 + .../media/regularlabs/js/colorpicker.min.js | 10 + .../regularlabs/media/regularlabs/js/form.js | 237 + .../media/regularlabs/js/form.min.js | 13 + .../media/regularlabs/js/jquery.cookie.js | 72 + .../media/regularlabs/js/jquery.cookie.min.js | 7 + .../media/regularlabs/js/multiselect.js | 195 + .../media/regularlabs/js/multiselect.min.js | 14 + .../media/regularlabs/js/regular.js | 145 + .../media/regularlabs/js/regular.min.js | 9 + .../media/regularlabs/js/script.js | 302 ++ .../media/regularlabs/js/script.min.js | 14 + .../media/regularlabs/js/simplecategories.js | 34 + .../regularlabs/js/simplecategories.min.js | 5 + .../media/regularlabs/js/textareaplus.js | 30 + .../media/regularlabs/js/textareaplus.min.js | 5 + .../media/regularlabs/js/toggler.js | 265 + .../media/regularlabs/js/toggler.min.js | 13 + .../media/regularlabs/less/codemirror.less | 51 + .../media/regularlabs/less/color.less | 290 ++ .../media/regularlabs/less/colorpicker.less | 78 + .../media/regularlabs/less/font.less | 384 ++ .../media/regularlabs/less/form.less | 107 + .../media/regularlabs/less/frontend.less | 78 + .../media/regularlabs/less/init.less | 2 + .../media/regularlabs/less/mixins.less | 8 + .../media/regularlabs/less/multiselect.less | 56 + .../media/regularlabs/less/popup.less | 70 + .../media/regularlabs/less/style.less | 371 ++ .../media/regularlabs/less/variables.less | 1 + .../regularlabs/media/sourcerer/css/popup.css | 21 + .../media/sourcerer/css/popup.min.css | 1 + .../media/sourcerer/images/tab.png | Bin 0 -> 3604 bytes .../media/sourcerer/images/wizard.gif | Bin 0 -> 28902 bytes .../regularlabs/media/sourcerer/js/script.js | 380 ++ .../media/sourcerer/js/script.min.js | 23 + .../media/sourcerer/less/popup.less | 24 + .../plugins/editors-xtd/modals/fields.xml | 77 + .../editors-xtd/modals/fields/article.php | 105 + .../plugins/editors-xtd/modals/helper.php | 31 + .../en-GB/en-GB.plg_editors-xtd_modals.ini | 19 + .../en-GB.plg_editors-xtd_modals.sys.ini | 13 + .../editors-xtd/modals/layouts/header.php | 20 + .../editors-xtd/modals/layouts/nav.php | 39 + .../plugins/editors-xtd/modals/modals.php | 28 + .../plugins/editors-xtd/modals/modals.xml | 47 + .../plugins/editors-xtd/modals/popup.php | 50 + .../plugins/editors-xtd/modals/popup.tmpl.php | 78 + .../modals/script.install.helper.php | 852 +++ .../editors-xtd/modals/script.install.php | 27 + .../plugins/editors-xtd/sourcerer/helper.php | 33 + .../en-GB/en-GB.plg_editors-xtd_sourcerer.ini | 19 + .../en-GB.plg_editors-xtd_sourcerer.sys.ini | 13 + .../plugins/editors-xtd/sourcerer/popup.php | 183 + .../sourcerer/script.install.helper.php | 878 ++++ .../editors-xtd/sourcerer/script.install.php | 27 + .../editors-xtd/sourcerer/sourcerer.php | 27 + .../editors-xtd/sourcerer/sourcerer.xml | 41 + .../advancedmodules/advancedmodules.php | 72 + .../advancedmodules/advancedmodules.xml | 49 + .../en-GB.plg_system_advancedmodules.ini | 23 + .../en-GB.plg_system_advancedmodules.sys.ini | 13 + .../hu-HU.plg_system_advancedmodules.ini | 25 + .../hu-HU.plg_system_advancedmodules.sys.ini | 15 + .../advancedmodules/script.install.helper.php | 852 +++ .../system/advancedmodules/script.install.php | 46 + .../system/advancedmodules/src/Document.php | 144 + .../system/advancedmodules/src/Helper.php | 55 + .../src/Helpers/advancedmodulehelper.php | 514 ++ .../Helpers/advancedmodulehelper_legacy.php | 472 ++ .../src/Helpers/modulehelper_legacy.php | 667 +++ .../advancedmodules/src/ModuleHelper.php | 29 + .../system/advancedmodules/src/Params.php | 35 + .../system/advancedmodules/src/Plugin.php | 379 ++ .../advancedmodules/vendor/autoload.php | 7 + .../vendor/composer/ClassLoader.php | 502 ++ .../advancedmodules/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 9 + .../vendor/composer/autoload_namespaces.php | 9 + .../vendor/composer/autoload_psr4.php | 10 + .../vendor/composer/autoload_real.php | 60 + .../vendor/composer/autoload_static.php | 30 + .../vendor/composer/installed.json | 1 + .../en-GB/en-GB.plg_system_modals.ini | 219 + .../en-GB/en-GB.plg_system_modals.sys.ini | 13 + .../plugins/system/modals/modal.php | 59 + .../plugins/system/modals/modals.php | 64 + .../plugins/system/modals/modals.xml | 323 ++ .../system/modals/script.install.helper.php | 852 +++ .../plugins/system/modals/script.install.php | 76 + .../plugins/system/modals/src/Clean.php | 37 + .../plugins/system/modals/src/Data.php | 168 + .../plugins/system/modals/src/Document.php | 215 + .../plugins/system/modals/src/File.php | 219 + .../plugins/system/modals/src/Gallery.php | 15 + .../plugins/system/modals/src/Helper.php | 83 + .../plugins/system/modals/src/Image.php | 15 + .../plugins/system/modals/src/Link.php | 378 ++ .../plugins/system/modals/src/Params.php | 180 + .../plugins/system/modals/src/Pass.php | 172 + .../plugins/system/modals/src/Plugin.php | 379 ++ .../plugins/system/modals/src/Protect.php | 50 + .../plugins/system/modals/src/Replace.php | 374 ++ .../plugins/system/modals/vendor/autoload.php | 7 + .../modals/vendor/composer/ClassLoader.php | 502 ++ .../system/modals/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 9 + .../vendor/composer/autoload_namespaces.php | 9 + .../modals/vendor/composer/autoload_psr4.php | 10 + .../modals/vendor/composer/autoload_real.php | 60 + .../vendor/composer/autoload_static.php | 30 + .../modals/vendor/composer/installed.json | 1 + .../en-GB/en-GB.plg_system_regularlabs.ini | 506 ++ .../en-GB.plg_system_regularlabs.sys.ini | 13 + .../hu-HU/hu-HU.plg_system_regularlabs.ini | 474 ++ .../hu-HU.plg_system_regularlabs.sys.ini | 13 + .../system/regularlabs/regularlabs.php | 197 + .../system/regularlabs/regularlabs.xml | 51 + .../regularlabs/script.install.helper.php | 878 ++++ .../system/regularlabs/script.install.php | 51 + .../system/regularlabs/src/AdminMenu.php | 155 + .../system/regularlabs/src/Application.php | 82 + .../system/regularlabs/src/DownloadKey.php | 52 + .../plugins/system/regularlabs/src/Params.php | 33 + .../system/regularlabs/src/QuickPage.php | 129 + .../system/regularlabs/src/SearchHelper.php | 38 + .../system/regularlabs/vendor/autoload.php | 7 + .../vendor/composer/ClassLoader.php | 502 ++ .../regularlabs/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 9 + .../vendor/composer/autoload_namespaces.php | 9 + .../vendor/composer/autoload_psr4.php | 10 + .../vendor/composer/autoload_real.php | 60 + .../vendor/composer/autoload_static.php | 30 + .../vendor/composer/installed.json | 1 + .../en-GB/en-GB.plg_system_sourcerer.ini | 92 + .../en-GB/en-GB.plg_system_sourcerer.sys.ini | 13 + .../sourcerer/script.install.helper.php | 878 ++++ .../system/sourcerer/script.install.php | 26 + .../plugins/system/sourcerer/sourcerer.php | 62 + .../plugins/system/sourcerer/sourcerer.xml | 249 + .../plugins/system/sourcerer/src/Area.php | 67 + .../plugins/system/sourcerer/src/Clean.php | 96 + .../plugins/system/sourcerer/src/Code.php | 123 + .../plugins/system/sourcerer/src/Helper.php | 116 + .../plugins/system/sourcerer/src/Params.php | 168 + .../plugins/system/sourcerer/src/Plugin.php | 379 ++ .../plugins/system/sourcerer/src/Protect.php | 48 + .../plugins/system/sourcerer/src/Replace.php | 604 +++ .../plugins/system/sourcerer/src/Security.php | 84 + .../system/sourcerer/vendor/autoload.php | 7 + .../sourcerer/vendor/composer/ClassLoader.php | 502 ++ .../system/sourcerer/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 9 + .../vendor/composer/autoload_namespaces.php | 9 + .../vendor/composer/autoload_psr4.php | 10 + .../vendor/composer/autoload_real.php | 60 + .../vendor/composer/autoload_static.php | 30 + .../sourcerer/vendor/composer/installed.json | 1 + 530 files changed, 77330 insertions(+) create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/advancedmodules.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/advancedmodules.xml create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/assignments.xml create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/config.xml create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/controller.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/controllers/module.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/controllers/modules.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/helpers/html/modules.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/helpers/modules.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/helpers/xml.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/language/en-GB/en-GB.com_advancedmodules.ini create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/language/en-GB/en-GB.com_advancedmodules.sys.ini create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/language/hu-HU/hu-HU.com_advancedmodules.ini create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/language/hu-HU/hu-HU.com_advancedmodules.sys.ini create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/layouts/joomla/edit/frontediting_modules.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/layouts/joomla/edit/params.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/layouts/joomla/searchtools/default.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/layouts/joomla/searchtools/default/bar.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/layouts/joomla/searchtools/grid/sort.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/layouts/toolbar/cancelselect.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/layouts/toolbar/newmodule.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/models/fields/modulesmenuid.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/models/fields/modulesmodule.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/models/fields/modulesposition.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/models/forms/advanced.xml create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/models/forms/filter_modules.xml create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/models/forms/module.xml create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/models/forms/moduleadmin.xml create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/models/module.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/models/modules.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/models/positions.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/models/select.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/script.install.helper.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/script.install.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/tables/advancedmodules.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/views/module/tmpl/edit.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/views/module/tmpl/edit_assignment.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/views/module/tmpl/edit_options.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/views/module/tmpl/edit_positions.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/views/module/tmpl/modal.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/views/module/view.html.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/views/module/view.json.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/tmpl/default.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/tmpl/default.xml create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/tmpl/default_batch.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/tmpl/default_batch_body.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/tmpl/default_batch_footer.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/tmpl/modal.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/view.html.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/views/positions/tmpl/modal.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/views/positions/view.html.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/views/preview/tmpl/default.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/views/preview/view.html.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/views/select/tmpl/default.php create mode 100644 deployed/regularlabs/administrator/components/com_advancedmodules/views/select/view.html.php create mode 100644 deployed/regularlabs/libraries/regularlabs/autoload.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/accesslevel.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/agents.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/ajax.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/akeebasubs.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/assignmentselection.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/block.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/checkbox.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/codeeditor.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/color.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/colorpicker.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/components.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/conditionselection.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/content.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/customfieldkey.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/customfieldvalue.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/datetime.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/dependency.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/easyblog.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/editor.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/filelist.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/flexicontent.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/form2content.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/geo.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/grouplevel.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/header.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/header_library.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/hikashop.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/hr.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/icons.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/isinstalled.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/k2.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/key.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/languages.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/license.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/list.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/loadlanguage.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/menuitems.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/mijoshop.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/modules.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/multiselect.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/note.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/onlypro.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/password.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/plaintext.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/radioimages.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/redshop.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/regions.txt create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/showon.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/simplecategories.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/slide.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/tags.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/templates.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/text.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/textareaplus.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/toggler.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/users.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/version.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/virtuemart.php create mode 100644 deployed/regularlabs/libraries/regularlabs/fields/zoo.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignment.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments/agents.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments/akeebasubs.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments/components.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments/content.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments/cookieconfirm.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments/datetime.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments/easyblog.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments/flexicontent.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments/form2content.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments/geo.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments/hikashop.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments/homepage.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments/ips.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments/k2.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments/languages.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments/menu.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments/mijoshop.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments/php.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments/redshop.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments/tags.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments/templates.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments/urls.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments/users.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments/virtuemart.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/assignments/zoo.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/cache.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/field.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/functions.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/groupfield.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/helper.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/html.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/htmlfix.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/licenses.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/mobile_detect.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/parameters.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/protect.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/search.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/string.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/tags.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/text.php create mode 100644 deployed/regularlabs/libraries/regularlabs/helpers/versions.php create mode 100644 deployed/regularlabs/libraries/regularlabs/regularlabs.xml create mode 100644 deployed/regularlabs/libraries/regularlabs/script.install.helper.php create mode 100644 deployed/regularlabs/libraries/regularlabs/script.install.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/ActionLogPlugin.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Alias.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Api/ConditionInterface.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/ArrayHelper.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Article.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Cache.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/Agent.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/AgentBrowser.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/AgentDevice.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/AgentOs.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/Akeebasubs.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/AkeebasubsLevel.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/AkeebasubsPagetype.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/Component.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/Content.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/ContentArticle.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/ContentCategory.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/ContentPagetype.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/Cookieconfirm.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/Date.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/DateDate.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/DateDay.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/DateMonth.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/DateSeason.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/DateTime.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/Easyblog.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/EasyblogCategory.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/EasyblogItem.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/EasyblogKeyword.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/EasyblogPagetype.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/EasyblogTag.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/Flexicontent.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/FlexicontentPagetype.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/FlexicontentTag.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/FlexicontentType.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/Form2content.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/Form2contentProject.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/Geo.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/GeoContinent.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/GeoCountry.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/GeoPostalcode.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/GeoRegion.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/Hikashop.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/HikashopCategory.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/HikashopPagetype.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/HikashopProduct.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/Homepage.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/Ip.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/K2.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/K2Category.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/K2Item.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/K2Pagetype.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/K2Tag.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/Language.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/Menu.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/Mijoshop.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/MijoshopCategory.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/MijoshopPagetype.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/MijoshopProduct.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/Php.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/Redshop.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/RedshopCategory.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/RedshopPagetype.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/RedshopProduct.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/Tag.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/Template.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/Url.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/User.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/UserAccesslevel.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/UserGrouplevel.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/UserUser.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/Virtuemart.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/VirtuemartCategory.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/VirtuemartPagetype.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/VirtuemartProduct.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/Zoo.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/ZooCategory.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/ZooItem.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Condition/ZooPagetype.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/ConditionContent.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Conditions.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/DB.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Database.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Date.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Document.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/EditorButton.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/EditorButtonHelper.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/EditorButtonPlugin.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/EditorButtonPopup.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Extension.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Field.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/FieldGroup.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/File.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Form.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Html.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/HtmlTag.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Http.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Image.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Language.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/License.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Log.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/MobileDetect.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Parameters.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/PluginTag.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Protect.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/RegEx.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/ShowOn.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/StringHelper.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Title.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Uri.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Version.php create mode 100644 deployed/regularlabs/libraries/regularlabs/src/Xml.php create mode 100644 deployed/regularlabs/libraries/regularlabs/vendor/autoload.php create mode 100644 deployed/regularlabs/libraries/regularlabs/vendor/composer/ClassLoader.php create mode 100644 deployed/regularlabs/libraries/regularlabs/vendor/composer/LICENSE create mode 100644 deployed/regularlabs/libraries/regularlabs/vendor/composer/autoload_classmap.php create mode 100644 deployed/regularlabs/libraries/regularlabs/vendor/composer/autoload_namespaces.php create mode 100644 deployed/regularlabs/libraries/regularlabs/vendor/composer/autoload_psr4.php create mode 100644 deployed/regularlabs/libraries/regularlabs/vendor/composer/autoload_real.php create mode 100644 deployed/regularlabs/libraries/regularlabs/vendor/composer/autoload_static.php create mode 100644 deployed/regularlabs/libraries/regularlabs/vendor/composer/installed.json create mode 100644 deployed/regularlabs/media/advancedmodules/js/frontediting.js create mode 100644 deployed/regularlabs/media/advancedmodules/js/frontediting.min.js create mode 100644 deployed/regularlabs/media/modals/css/bootstrap.css create mode 100644 deployed/regularlabs/media/modals/css/bootstrap.min.css create mode 100644 deployed/regularlabs/media/modals/css/colorbox1.css create mode 100644 deployed/regularlabs/media/modals/css/colorbox1.min.css create mode 100644 deployed/regularlabs/media/modals/css/colorbox2.css create mode 100644 deployed/regularlabs/media/modals/css/colorbox2.min.css create mode 100644 deployed/regularlabs/media/modals/css/colorbox3.css create mode 100644 deployed/regularlabs/media/modals/css/colorbox3.min.css create mode 100644 deployed/regularlabs/media/modals/css/colorbox4.css create mode 100644 deployed/regularlabs/media/modals/css/colorbox4.min.css create mode 100644 deployed/regularlabs/media/modals/css/colorbox5.css create mode 100644 deployed/regularlabs/media/modals/css/colorbox5.min.css create mode 100644 deployed/regularlabs/media/modals/css/index.html create mode 100644 deployed/regularlabs/media/modals/images/bootstrap/controls.png create mode 100644 deployed/regularlabs/media/modals/images/bootstrap/index.html create mode 100644 deployed/regularlabs/media/modals/images/bootstrap/loading.gif create mode 100644 deployed/regularlabs/media/modals/images/colorbox1/border.png create mode 100644 deployed/regularlabs/media/modals/images/colorbox1/controls.png create mode 100644 deployed/regularlabs/media/modals/images/colorbox1/index.html create mode 100644 deployed/regularlabs/media/modals/images/colorbox1/loading.gif create mode 100644 deployed/regularlabs/media/modals/images/colorbox1/loading_background.png create mode 100644 deployed/regularlabs/media/modals/images/colorbox1/overlay.png create mode 100644 deployed/regularlabs/media/modals/images/colorbox2/controls.png create mode 100644 deployed/regularlabs/media/modals/images/colorbox2/index.html create mode 100644 deployed/regularlabs/media/modals/images/colorbox2/loading.gif create mode 100644 deployed/regularlabs/media/modals/images/colorbox3/controls.png create mode 100644 deployed/regularlabs/media/modals/images/colorbox3/index.html create mode 100644 deployed/regularlabs/media/modals/images/colorbox3/loading.gif create mode 100644 deployed/regularlabs/media/modals/images/colorbox4/border1.png create mode 100644 deployed/regularlabs/media/modals/images/colorbox4/border2.png create mode 100644 deployed/regularlabs/media/modals/images/colorbox4/index.html create mode 100644 deployed/regularlabs/media/modals/images/colorbox4/loading.gif create mode 100644 deployed/regularlabs/media/modals/images/colorbox5/border.png create mode 100644 deployed/regularlabs/media/modals/images/colorbox5/controls.png create mode 100644 deployed/regularlabs/media/modals/images/colorbox5/index.html create mode 100644 deployed/regularlabs/media/modals/images/colorbox5/loading.gif create mode 100644 deployed/regularlabs/media/modals/images/colorbox5/loading_background.png create mode 100644 deployed/regularlabs/media/modals/images/index.html create mode 100644 deployed/regularlabs/media/modals/index.html create mode 100644 deployed/regularlabs/media/modals/js/index.html create mode 100644 deployed/regularlabs/media/modals/js/jquery.colorbox-min.js create mode 100644 deployed/regularlabs/media/modals/js/jquery.colorbox.js create mode 100644 deployed/regularlabs/media/modals/js/jquery.touchSwipe.min.js create mode 100644 deployed/regularlabs/media/modals/js/popup.js create mode 100644 deployed/regularlabs/media/modals/js/popup.min.js create mode 100644 deployed/regularlabs/media/modals/js/script.js create mode 100644 deployed/regularlabs/media/modals/js/script.min.js create mode 100644 deployed/regularlabs/media/modals/less/base.less create mode 100644 deployed/regularlabs/media/modals/less/bootstrap.less create mode 100644 deployed/regularlabs/media/modals/less/colorbox1.less create mode 100644 deployed/regularlabs/media/modals/less/colorbox2.less create mode 100644 deployed/regularlabs/media/modals/less/colorbox3.less create mode 100644 deployed/regularlabs/media/modals/less/colorbox4.less create mode 100644 deployed/regularlabs/media/modals/less/colorbox5.less create mode 100644 deployed/regularlabs/media/modals/less/index.html create mode 100644 deployed/regularlabs/media/regularlabs/css/codemirror.css create mode 100644 deployed/regularlabs/media/regularlabs/css/codemirror.min.css create mode 100644 deployed/regularlabs/media/regularlabs/css/color.css create mode 100644 deployed/regularlabs/media/regularlabs/css/color.min.css create mode 100644 deployed/regularlabs/media/regularlabs/css/colorpicker.css create mode 100644 deployed/regularlabs/media/regularlabs/css/colorpicker.min.css create mode 100644 deployed/regularlabs/media/regularlabs/css/form.css create mode 100644 deployed/regularlabs/media/regularlabs/css/form.min.css create mode 100644 deployed/regularlabs/media/regularlabs/css/frontend.css create mode 100644 deployed/regularlabs/media/regularlabs/css/frontend.min.css create mode 100644 deployed/regularlabs/media/regularlabs/css/multiselect.css create mode 100644 deployed/regularlabs/media/regularlabs/css/multiselect.min.css create mode 100644 deployed/regularlabs/media/regularlabs/css/popup.css create mode 100644 deployed/regularlabs/media/regularlabs/css/popup.min.css create mode 100644 deployed/regularlabs/media/regularlabs/css/style.css create mode 100644 deployed/regularlabs/media/regularlabs/css/style.min.css create mode 100644 deployed/regularlabs/media/regularlabs/fonts/RegularLabs.eot create mode 100644 deployed/regularlabs/media/regularlabs/fonts/RegularLabs.svg create mode 100644 deployed/regularlabs/media/regularlabs/fonts/RegularLabs.ttf create mode 100644 deployed/regularlabs/media/regularlabs/fonts/RegularLabs.woff create mode 100644 deployed/regularlabs/media/regularlabs/fonts/RegularLabsIcons.eot create mode 100644 deployed/regularlabs/media/regularlabs/fonts/RegularLabsIcons.svg create mode 100644 deployed/regularlabs/media/regularlabs/fonts/RegularLabsIcons.ttf create mode 100644 deployed/regularlabs/media/regularlabs/fonts/RegularLabsIcons.woff create mode 100644 deployed/regularlabs/media/regularlabs/images/icon-color.png create mode 100644 deployed/regularlabs/media/regularlabs/images/logo.png create mode 100644 deployed/regularlabs/media/regularlabs/images/minicolors.png create mode 100644 deployed/regularlabs/media/regularlabs/js/codemirror.js create mode 100644 deployed/regularlabs/media/regularlabs/js/codemirror.min.js create mode 100644 deployed/regularlabs/media/regularlabs/js/color.js create mode 100644 deployed/regularlabs/media/regularlabs/js/color.min.js create mode 100644 deployed/regularlabs/media/regularlabs/js/colorpicker.js create mode 100644 deployed/regularlabs/media/regularlabs/js/colorpicker.min.js create mode 100644 deployed/regularlabs/media/regularlabs/js/form.js create mode 100644 deployed/regularlabs/media/regularlabs/js/form.min.js create mode 100644 deployed/regularlabs/media/regularlabs/js/jquery.cookie.js create mode 100644 deployed/regularlabs/media/regularlabs/js/jquery.cookie.min.js create mode 100644 deployed/regularlabs/media/regularlabs/js/multiselect.js create mode 100644 deployed/regularlabs/media/regularlabs/js/multiselect.min.js create mode 100644 deployed/regularlabs/media/regularlabs/js/regular.js create mode 100644 deployed/regularlabs/media/regularlabs/js/regular.min.js create mode 100644 deployed/regularlabs/media/regularlabs/js/script.js create mode 100644 deployed/regularlabs/media/regularlabs/js/script.min.js create mode 100644 deployed/regularlabs/media/regularlabs/js/simplecategories.js create mode 100644 deployed/regularlabs/media/regularlabs/js/simplecategories.min.js create mode 100644 deployed/regularlabs/media/regularlabs/js/textareaplus.js create mode 100644 deployed/regularlabs/media/regularlabs/js/textareaplus.min.js create mode 100644 deployed/regularlabs/media/regularlabs/js/toggler.js create mode 100644 deployed/regularlabs/media/regularlabs/js/toggler.min.js create mode 100644 deployed/regularlabs/media/regularlabs/less/codemirror.less create mode 100644 deployed/regularlabs/media/regularlabs/less/color.less create mode 100644 deployed/regularlabs/media/regularlabs/less/colorpicker.less create mode 100644 deployed/regularlabs/media/regularlabs/less/font.less create mode 100644 deployed/regularlabs/media/regularlabs/less/form.less create mode 100644 deployed/regularlabs/media/regularlabs/less/frontend.less create mode 100644 deployed/regularlabs/media/regularlabs/less/init.less create mode 100644 deployed/regularlabs/media/regularlabs/less/mixins.less create mode 100644 deployed/regularlabs/media/regularlabs/less/multiselect.less create mode 100644 deployed/regularlabs/media/regularlabs/less/popup.less create mode 100644 deployed/regularlabs/media/regularlabs/less/style.less create mode 100644 deployed/regularlabs/media/regularlabs/less/variables.less create mode 100644 deployed/regularlabs/media/sourcerer/css/popup.css create mode 100644 deployed/regularlabs/media/sourcerer/css/popup.min.css create mode 100644 deployed/regularlabs/media/sourcerer/images/tab.png create mode 100644 deployed/regularlabs/media/sourcerer/images/wizard.gif create mode 100644 deployed/regularlabs/media/sourcerer/js/script.js create mode 100644 deployed/regularlabs/media/sourcerer/js/script.min.js create mode 100644 deployed/regularlabs/media/sourcerer/less/popup.less create mode 100644 deployed/regularlabs/plugins/editors-xtd/modals/fields.xml create mode 100644 deployed/regularlabs/plugins/editors-xtd/modals/fields/article.php create mode 100644 deployed/regularlabs/plugins/editors-xtd/modals/helper.php create mode 100644 deployed/regularlabs/plugins/editors-xtd/modals/language/en-GB/en-GB.plg_editors-xtd_modals.ini create mode 100644 deployed/regularlabs/plugins/editors-xtd/modals/language/en-GB/en-GB.plg_editors-xtd_modals.sys.ini create mode 100644 deployed/regularlabs/plugins/editors-xtd/modals/layouts/header.php create mode 100644 deployed/regularlabs/plugins/editors-xtd/modals/layouts/nav.php create mode 100644 deployed/regularlabs/plugins/editors-xtd/modals/modals.php create mode 100644 deployed/regularlabs/plugins/editors-xtd/modals/modals.xml create mode 100644 deployed/regularlabs/plugins/editors-xtd/modals/popup.php create mode 100644 deployed/regularlabs/plugins/editors-xtd/modals/popup.tmpl.php create mode 100644 deployed/regularlabs/plugins/editors-xtd/modals/script.install.helper.php create mode 100644 deployed/regularlabs/plugins/editors-xtd/modals/script.install.php create mode 100644 deployed/regularlabs/plugins/editors-xtd/sourcerer/helper.php create mode 100644 deployed/regularlabs/plugins/editors-xtd/sourcerer/language/en-GB/en-GB.plg_editors-xtd_sourcerer.ini create mode 100644 deployed/regularlabs/plugins/editors-xtd/sourcerer/language/en-GB/en-GB.plg_editors-xtd_sourcerer.sys.ini create mode 100644 deployed/regularlabs/plugins/editors-xtd/sourcerer/popup.php create mode 100644 deployed/regularlabs/plugins/editors-xtd/sourcerer/script.install.helper.php create mode 100644 deployed/regularlabs/plugins/editors-xtd/sourcerer/script.install.php create mode 100644 deployed/regularlabs/plugins/editors-xtd/sourcerer/sourcerer.php create mode 100644 deployed/regularlabs/plugins/editors-xtd/sourcerer/sourcerer.xml create mode 100644 deployed/regularlabs/plugins/system/advancedmodules/advancedmodules.php create mode 100644 deployed/regularlabs/plugins/system/advancedmodules/advancedmodules.xml create mode 100644 deployed/regularlabs/plugins/system/advancedmodules/language/en-GB/en-GB.plg_system_advancedmodules.ini create mode 100644 deployed/regularlabs/plugins/system/advancedmodules/language/en-GB/en-GB.plg_system_advancedmodules.sys.ini create mode 100644 deployed/regularlabs/plugins/system/advancedmodules/language/hu-HU/hu-HU.plg_system_advancedmodules.ini create mode 100644 deployed/regularlabs/plugins/system/advancedmodules/language/hu-HU/hu-HU.plg_system_advancedmodules.sys.ini create mode 100644 deployed/regularlabs/plugins/system/advancedmodules/script.install.helper.php create mode 100644 deployed/regularlabs/plugins/system/advancedmodules/script.install.php create mode 100644 deployed/regularlabs/plugins/system/advancedmodules/src/Document.php create mode 100644 deployed/regularlabs/plugins/system/advancedmodules/src/Helper.php create mode 100644 deployed/regularlabs/plugins/system/advancedmodules/src/Helpers/advancedmodulehelper.php create mode 100644 deployed/regularlabs/plugins/system/advancedmodules/src/Helpers/advancedmodulehelper_legacy.php create mode 100644 deployed/regularlabs/plugins/system/advancedmodules/src/Helpers/modulehelper_legacy.php create mode 100644 deployed/regularlabs/plugins/system/advancedmodules/src/ModuleHelper.php create mode 100644 deployed/regularlabs/plugins/system/advancedmodules/src/Params.php create mode 100644 deployed/regularlabs/plugins/system/advancedmodules/src/Plugin.php create mode 100644 deployed/regularlabs/plugins/system/advancedmodules/vendor/autoload.php create mode 100644 deployed/regularlabs/plugins/system/advancedmodules/vendor/composer/ClassLoader.php create mode 100644 deployed/regularlabs/plugins/system/advancedmodules/vendor/composer/LICENSE create mode 100644 deployed/regularlabs/plugins/system/advancedmodules/vendor/composer/autoload_classmap.php create mode 100644 deployed/regularlabs/plugins/system/advancedmodules/vendor/composer/autoload_namespaces.php create mode 100644 deployed/regularlabs/plugins/system/advancedmodules/vendor/composer/autoload_psr4.php create mode 100644 deployed/regularlabs/plugins/system/advancedmodules/vendor/composer/autoload_real.php create mode 100644 deployed/regularlabs/plugins/system/advancedmodules/vendor/composer/autoload_static.php create mode 100644 deployed/regularlabs/plugins/system/advancedmodules/vendor/composer/installed.json create mode 100644 deployed/regularlabs/plugins/system/modals/language/en-GB/en-GB.plg_system_modals.ini create mode 100644 deployed/regularlabs/plugins/system/modals/language/en-GB/en-GB.plg_system_modals.sys.ini create mode 100644 deployed/regularlabs/plugins/system/modals/modal.php create mode 100644 deployed/regularlabs/plugins/system/modals/modals.php create mode 100644 deployed/regularlabs/plugins/system/modals/modals.xml create mode 100644 deployed/regularlabs/plugins/system/modals/script.install.helper.php create mode 100644 deployed/regularlabs/plugins/system/modals/script.install.php create mode 100644 deployed/regularlabs/plugins/system/modals/src/Clean.php create mode 100644 deployed/regularlabs/plugins/system/modals/src/Data.php create mode 100644 deployed/regularlabs/plugins/system/modals/src/Document.php create mode 100644 deployed/regularlabs/plugins/system/modals/src/File.php create mode 100644 deployed/regularlabs/plugins/system/modals/src/Gallery.php create mode 100644 deployed/regularlabs/plugins/system/modals/src/Helper.php create mode 100644 deployed/regularlabs/plugins/system/modals/src/Image.php create mode 100644 deployed/regularlabs/plugins/system/modals/src/Link.php create mode 100644 deployed/regularlabs/plugins/system/modals/src/Params.php create mode 100644 deployed/regularlabs/plugins/system/modals/src/Pass.php create mode 100644 deployed/regularlabs/plugins/system/modals/src/Plugin.php create mode 100644 deployed/regularlabs/plugins/system/modals/src/Protect.php create mode 100644 deployed/regularlabs/plugins/system/modals/src/Replace.php create mode 100644 deployed/regularlabs/plugins/system/modals/vendor/autoload.php create mode 100644 deployed/regularlabs/plugins/system/modals/vendor/composer/ClassLoader.php create mode 100644 deployed/regularlabs/plugins/system/modals/vendor/composer/LICENSE create mode 100644 deployed/regularlabs/plugins/system/modals/vendor/composer/autoload_classmap.php create mode 100644 deployed/regularlabs/plugins/system/modals/vendor/composer/autoload_namespaces.php create mode 100644 deployed/regularlabs/plugins/system/modals/vendor/composer/autoload_psr4.php create mode 100644 deployed/regularlabs/plugins/system/modals/vendor/composer/autoload_real.php create mode 100644 deployed/regularlabs/plugins/system/modals/vendor/composer/autoload_static.php create mode 100644 deployed/regularlabs/plugins/system/modals/vendor/composer/installed.json create mode 100644 deployed/regularlabs/plugins/system/regularlabs/language/en-GB/en-GB.plg_system_regularlabs.ini create mode 100644 deployed/regularlabs/plugins/system/regularlabs/language/en-GB/en-GB.plg_system_regularlabs.sys.ini create mode 100644 deployed/regularlabs/plugins/system/regularlabs/language/hu-HU/hu-HU.plg_system_regularlabs.ini create mode 100644 deployed/regularlabs/plugins/system/regularlabs/language/hu-HU/hu-HU.plg_system_regularlabs.sys.ini create mode 100644 deployed/regularlabs/plugins/system/regularlabs/regularlabs.php create mode 100644 deployed/regularlabs/plugins/system/regularlabs/regularlabs.xml create mode 100644 deployed/regularlabs/plugins/system/regularlabs/script.install.helper.php create mode 100644 deployed/regularlabs/plugins/system/regularlabs/script.install.php create mode 100644 deployed/regularlabs/plugins/system/regularlabs/src/AdminMenu.php create mode 100644 deployed/regularlabs/plugins/system/regularlabs/src/Application.php create mode 100644 deployed/regularlabs/plugins/system/regularlabs/src/DownloadKey.php create mode 100644 deployed/regularlabs/plugins/system/regularlabs/src/Params.php create mode 100644 deployed/regularlabs/plugins/system/regularlabs/src/QuickPage.php create mode 100644 deployed/regularlabs/plugins/system/regularlabs/src/SearchHelper.php create mode 100644 deployed/regularlabs/plugins/system/regularlabs/vendor/autoload.php create mode 100644 deployed/regularlabs/plugins/system/regularlabs/vendor/composer/ClassLoader.php create mode 100644 deployed/regularlabs/plugins/system/regularlabs/vendor/composer/LICENSE create mode 100644 deployed/regularlabs/plugins/system/regularlabs/vendor/composer/autoload_classmap.php create mode 100644 deployed/regularlabs/plugins/system/regularlabs/vendor/composer/autoload_namespaces.php create mode 100644 deployed/regularlabs/plugins/system/regularlabs/vendor/composer/autoload_psr4.php create mode 100644 deployed/regularlabs/plugins/system/regularlabs/vendor/composer/autoload_real.php create mode 100644 deployed/regularlabs/plugins/system/regularlabs/vendor/composer/autoload_static.php create mode 100644 deployed/regularlabs/plugins/system/regularlabs/vendor/composer/installed.json create mode 100644 deployed/regularlabs/plugins/system/sourcerer/language/en-GB/en-GB.plg_system_sourcerer.ini create mode 100644 deployed/regularlabs/plugins/system/sourcerer/language/en-GB/en-GB.plg_system_sourcerer.sys.ini create mode 100644 deployed/regularlabs/plugins/system/sourcerer/script.install.helper.php create mode 100644 deployed/regularlabs/plugins/system/sourcerer/script.install.php create mode 100644 deployed/regularlabs/plugins/system/sourcerer/sourcerer.php create mode 100644 deployed/regularlabs/plugins/system/sourcerer/sourcerer.xml create mode 100644 deployed/regularlabs/plugins/system/sourcerer/src/Area.php create mode 100644 deployed/regularlabs/plugins/system/sourcerer/src/Clean.php create mode 100644 deployed/regularlabs/plugins/system/sourcerer/src/Code.php create mode 100644 deployed/regularlabs/plugins/system/sourcerer/src/Helper.php create mode 100644 deployed/regularlabs/plugins/system/sourcerer/src/Params.php create mode 100644 deployed/regularlabs/plugins/system/sourcerer/src/Plugin.php create mode 100644 deployed/regularlabs/plugins/system/sourcerer/src/Protect.php create mode 100644 deployed/regularlabs/plugins/system/sourcerer/src/Replace.php create mode 100644 deployed/regularlabs/plugins/system/sourcerer/src/Security.php create mode 100644 deployed/regularlabs/plugins/system/sourcerer/vendor/autoload.php create mode 100644 deployed/regularlabs/plugins/system/sourcerer/vendor/composer/ClassLoader.php create mode 100644 deployed/regularlabs/plugins/system/sourcerer/vendor/composer/LICENSE create mode 100644 deployed/regularlabs/plugins/system/sourcerer/vendor/composer/autoload_classmap.php create mode 100644 deployed/regularlabs/plugins/system/sourcerer/vendor/composer/autoload_namespaces.php create mode 100644 deployed/regularlabs/plugins/system/sourcerer/vendor/composer/autoload_psr4.php create mode 100644 deployed/regularlabs/plugins/system/sourcerer/vendor/composer/autoload_real.php create mode 100644 deployed/regularlabs/plugins/system/sourcerer/vendor/composer/autoload_static.php create mode 100644 deployed/regularlabs/plugins/system/sourcerer/vendor/composer/installed.json diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/advancedmodules.php b/deployed/regularlabs/administrator/components/com_advancedmodules/advancedmodules.php new file mode 100644 index 00000000..463b6427 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/advancedmodules.php @@ -0,0 +1,58 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +JHtml::_('behavior.tabstate'); + +if ( ! JFactory::getUser()->authorise('core.manage', 'com_modules')) +{ + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); +} + +jimport('joomla.filesystem.file'); + +// return if Regular Labs Library plugin is not installed +if ( + ! is_file(JPATH_PLUGINS . '/system/regularlabs/regularlabs.xml') + || ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php') +) +{ + $msg = JText::_('AMM_REGULAR_LABS_LIBRARY_NOT_INSTALLED') + . ' ' . JText::sprintf('AMM_EXTENSION_CAN_NOT_FUNCTION', JText::_('COM_ADVANCEDMODULES')); + JFactory::getApplication()->enqueueMessage($msg, 'error'); + + return; +} + +// give notice if Regular Labs Library plugin is not enabled +if ( ! JPluginHelper::isEnabled('system', 'regularlabs')) +{ + $msg = JText::_('AMM_REGULAR_LABS_LIBRARY_NOT_ENABLED') + . ' ' . JText::sprintf('AMM_EXTENSION_CAN_NOT_FUNCTION', JText::_('COM_ADVANCEDMODULES')); + JFactory::getApplication()->enqueueMessage($msg, 'notice'); +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +use RegularLabs\Library\Language as RL_Language; + +RL_Language::load('plg_system_regularlabs'); +RL_Language::load('com_modules', JPATH_ADMINISTRATOR); + +$controller = JControllerLegacy::getInstance('AdvancedModules'); +$controller->execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/advancedmodules.xml b/deployed/regularlabs/administrator/components/com_advancedmodules/advancedmodules.xml new file mode 100644 index 00000000..e40985ee --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/advancedmodules.xml @@ -0,0 +1,53 @@ + + + com_advancedmodules + COM_ADVANCEDMODULES_DESC + 7.7.1 + July 2018 + Regular Labs (Peter van Westen) + info@regularlabs.com + https://www.regularlabs.com + Copyright © 2018 Regular Labs - All Rights Reserved + http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + + script.install.php + + + + https://download.regularlabs.com/updates.xml?e=advancedmodulemanager&type=.xml + + + + + + advancedmodules.php + assignments.xml + config.xml + controller.php + script.install.helper.php + controllers + helpers + language + layouts + models + tables + views + + + + + advancedmodules.php + controller.php + empty.xml + controllers + helpers + layouts + models + tables + views + + + + js + + diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/assignments.xml b/deployed/regularlabs/administrator/components/com_advancedmodules/assignments.xml new file mode 100644 index 00000000..b449efcb --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/assignments.xml @@ -0,0 +1,318 @@ + + +
+ +
+ +
+ + + + +
+ + +
+ +
+ +
+ +
+ +
+ + + + + + + + +
+ +
+ + + + + + + + + + +
+ +
+ + + + + + + +
+ +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + +
+ + + +
+ +
+ + + + + + + + + + + +
+ +
+ + + + + + + + +
+ +
+ + + + +
+ +
+ + + + + +
+ +
+ + + +
+ +
+ + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/config.xml b/deployed/regularlabs/administrator/components/com_advancedmodules/config.xml new file mode 100644 index 00000000..36746b2f --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/config.xml @@ -0,0 +1,284 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/controller.php b/deployed/regularlabs/administrator/components/com_advancedmodules/controller.php new file mode 100644 index 00000000..fdfff24f --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/controller.php @@ -0,0 +1,90 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * Modules manager master display controller. + */ +class AdvancedModulesController extends JControllerLegacy +{ + /** + * @var string The default view. + */ + protected $default_view = 'modules'; + + /** + * Method to display a view. + * + * @param boolean $cachable If true, the view output will be cached + * @param array|boolean $urlparams An array of safe url parameters and their variable types, for valid values see {@link JFilterInput::clean()} + * + * @return JController This object to support chaining. + */ + public function display($cachable = false, $urlparams = false) + { + $id = $this->input->getInt('id'); + + $document = JFactory::getDocument(); + + // For JSON requests + if ($document->getType() == 'json') + { + + $view = new ModulesViewModule; + + // Get/Create the model + if ($model = new ModulesModelModule) + { + // Checkin table entry + if ( ! $model->checkout($id)) + { + JFactory::getApplication()->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_CHECKIN_USER_MISMATCH'), 'error'); + + return false; + } + + // Push the model into the view (as default) + $view->setModel($model, true); + } + + $view->document = $document; + + return $view->display(); + } + + require_once JPATH_COMPONENT . '/helpers/modules.php'; + + $layout = $this->input->get('layout', 'edit'); + $id = $this->input->getInt('id'); + + // Check for edit form. + if ($layout == 'edit' && $id && ! $this->checkEditId('com_advancedmodules.edit.module', $id)) + { + // Somehow the person just went to the form - we don't allow that. + $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); + $this->setMessage($this->getError(), 'error'); + $this->setRedirect(JRoute::_('index.php?option=com_advancedmodules&view=modules', false)); + + return false; + } + + // Load the submenu. + ModulesHelper::addSubmenu($this->input->get('view', 'modules')); + + return parent::display(); + } +} diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/controllers/module.php b/deployed/regularlabs/administrator/components/com_advancedmodules/controllers/module.php new file mode 100644 index 00000000..22c5cf22 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/controllers/module.php @@ -0,0 +1,477 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * Module controller class. + */ +class AdvancedModulesControllerModule extends JControllerForm +{ + /** + * Override parent add method. + * + * @return mixed True if the record can be added, a JError object if not. + */ + public function add() + { + $app = JFactory::getApplication(); + + // Get the result of the parent method. If an error, just return it. + $result = parent::add(); + + if ($result instanceof Exception) + { + return $result; + } + + // Look for the Extension ID. + $extensionId = $app->input->get('eid', 0, 'int'); + + if (empty($extensionId)) + { + $redirectUrl = 'index.php?option=' . $this->option . '&view=' . $this->view_item . '&layout=edit'; + + $this->setRedirect(JRoute::_($redirectUrl, false)); + + throw new Exception(JText::_('COM_MODULES_ERROR_INVALID_EXTENSION'), 500); + } + + $app->setUserState('com_advancedmodules.add.module.extension_id', $extensionId); + $app->setUserState('com_advancedmodules.add.module.params', null); + + // Parameters could be coming in for a new item, so let's set them. + $params = $app->input->get('params', [], 'array'); + $app->setUserState('com_advancedmodules.add.module.params', $params); + } + + /** + * Override parent cancel method to reset the add module state. + * + * @param string $key The name of the primary key of the URL variable. + * + * @return boolean True if access level checks pass, false otherwise. + */ + public function cancel($key = null) + { + $app = JFactory::getApplication(); + + $result = parent::cancel(); + + $app->setUserState('com_advancedmodules.add.module.extension_id', null); + $app->setUserState('com_advancedmodules.add.module.params', null); + + if ( ! JFactory::getApplication()->isClient('administrator')) + { + $returnUri = $this->input->post->get('return', null, 'base64'); + $returnUri = ! empty($returnUri) ? base64_decode(urldecode($returnUri)) : JUri::base(); + $this->setRedirect($returnUri); + $this->redirect(); + } + + return $result; + } + + /** + * Override parent allowSave method. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + */ + protected function allowSave($data, $key = 'id') + { + // Use custom position if selected + if (isset($data['custom_position'])) + { + if (empty($data['position'])) + { + $data['position'] = $data['custom_position']; + } + + unset($data['custom_position']); + } + + return parent::allowSave($data, $key); + } + + /** + * Override parent allowAdd method. + * + * @param array $data An array of input data. + * + * @return boolean + */ + protected function allowAdd($data = []) + { + $user = JFactory::getUser(); + + return ($user->authorise('core.create', 'com_modules') || count($user->getAuthorisedCategories('com_modules', 'core.create'))); + } + + /** + * Method override to check if you can edit an existing record. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + */ + protected function allowEdit($data = [], $key = 'id') + { + // Initialise variables. + $recordId = (int) isset($data[$key]) ? $data[$key] : 0; + $user = JFactory::getUser(); + + // Zero record (id:0), return component edit permission by calling parent controller method + if ( ! $recordId) + { + return parent::allowEdit($data, $key); + } + + // Check edit on the record asset (explicit or inherited) + if ($user->authorise('core.edit', 'com_modules.module.' . $recordId)) + { + return true; + } + + return false; + } + + /** + * Method to run batch operations. + * + * @param string $model The model + * + * @return boolean True on success. + */ + public function batch($model = null) + { + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + // Set the model + $model = $this->getModel('Module', '', []); + + // Preset the redirect + $redirectUrl = 'index.php?option=com_advancedmodules&view=modules' . $this->getRedirectToListAppend(); + + $this->setRedirect(JRoute::_($redirectUrl, false)); + + return parent::batch($model); + } + + /** + * Function that allows child controller access to model data after the data has been saved. + * + * @param JModelLegacy $model The data model object. + * @param array $validData The validated data. + * + * @return void + */ + protected function postSaveHook(JModelLegacy $model, $validData = []) + { + $app = JFactory::getApplication(); + $task = $this->getTask(); + + switch ($task) + { + case 'save2new': + $app->setUserState('com_advancedmodules.add.module.extension_id', $model->getState('module.extension_id')); + break; + + default: + $app->setUserState('com_advancedmodules.add.module.extension_id', null); + break; + } + + $app->setUserState('com_advancedmodules.add.module.params', null); + } + + /** + * Method to save a record. + * + * @param string $key The name of the primary key of the URL variable. + * @param string $urlVar The name of the URL variable if different from the primary key + * + * @return boolean True if successful, false otherwise. + */ + public function save($key = null, $urlVar = null) + { + if ( ! JSession::checkToken()) + { + JFactory::getApplication()->redirect('index.php', JText::_('JINVALID_TOKEN')); + } + + if (JFactory::getDocument()->getType() == 'json') + { + $model = $this->getModel(); + $data = $this->input->post->get('jform', [], 'array'); + $item = $model->getItem($this->input->get('id')); + $properties = $item->getProperties(); + + // Replace changed properties + $data = array_replace_recursive($properties, $data); + + if ( ! empty($data['assigned'])) + { + $data['assigned'] = array_map('abs', $data['assigned']); + } + + // Add new data to input before process by parent save() + $this->input->post->set('jform', $data); + + // Add path of forms directory + JForm::addFormPath(JPATH_ADMINISTRATOR . '/components/com_advancedmodules/models/forms'); + } + + if ( ! JFactory::getApplication()->isClient('administrator')) + { + $this->saveFrontend($key, $urlVar); + } + + parent::save($key, $urlVar); + } + + public function saveFrontend($key = null, $urlVar = null) + { + // Check for request forgeries. + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + $app = JFactory::getApplication(); + $lang = JFactory::getLanguage(); + $model = $this->getModel(); + $table = $model->getTable(); + $data = $this->input->post->get('jform', [], 'array'); + $checkin = property_exists($table, 'checked_out'); + $context = "$this->option.edit.$this->context"; + $task = $this->getTask(); + + $returnUri = $this->input->post->get('current', null, 'base64'); + if (empty($returnUri)) + { + $returnUri = $this->input->post->get('return', null, 'base64'); + } + $returnUri = ! empty($returnUri) ? base64_decode(urldecode($returnUri)) : JUri::base(); + + // Determine the name of the primary key for the data. + if (empty($key)) + { + $key = $table->getKeyName(); + } + + // To avoid data collisions the urlVar may be different from the primary key. + if (empty($urlVar)) + { + $urlVar = $key; + } + + $recordId = $this->input->getInt($urlVar); + + // Populate the row id from the session. + $data[$key] = $recordId; + + // Access check. + if ( ! $this->allowSave($data, $key)) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED')); + $this->setMessage($this->getError(), 'error'); + + $this->setRedirect($returnUri); + + return false; + } + + // Validate the posted data. + // Sometimes the form needs some posted data, such as for plugins and modules. + $form = $model->getForm($data, false); + + if ( ! $form) + { + $app->enqueueMessage($model->getError(), 'error'); + + return false; + } + + // Test whether the data is valid. + $validData = $model->validate($form, $data); + + // Check for validation errors. + if ($validData === false) + { + // Get the validation messages. + $errors = $model->getErrors(); + + // Push up to three validation messages out to the user. + for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++) + { + if ($errors[$i] instanceof Exception) + { + $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); + continue; + } + + $app->enqueueMessage($errors[$i], 'warning'); + } + + // Save the data in the session. + $app->setUserState($context . '.data', $data); + + // Redirect back to the edit screen. + $this->setRedirect($returnUri); + + return false; + } + + if ( ! isset($validData['tags'])) + { + $validData['tags'] = null; + } + + // Redirect back to the edit screen. + $this->setRedirect($returnUri); + + // Attempt to save the data. + if ( ! $model->save($validData)) + { + // Save the data in the session. + $app->setUserState($context . '.data', $validData); + + // Redirect back to the edit screen. + $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError())); + $this->setMessage($this->getError(), 'error'); + + return false; + } + + // Save succeeded, so check-in the record. + if ($checkin && $model->checkin($validData[$key]) === false) + { + // Save the data in the session. + $app->setUserState($context . '.data', $validData); + + // Check-in failed, so go back to the record and display a notice. + $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError())); + $this->setMessage($this->getError(), 'error'); + + return false; + } + + $this->setMessage( + JText::_( + ($lang->hasKey($this->text_prefix . ($recordId == 0 && $app->isClient('site') ? '_SUBMIT' : '') . '_SAVE_SUCCESS') + ? $this->text_prefix + : 'JLIB_APPLICATION') . ($recordId == 0 && $app->isClient('site') ? '_SUBMIT' : '') . '_SAVE_SUCCESS' + ) + ); + + // Redirect the user and adjust session state based on the chosen task. + switch ($task) + { + case 'apply': + $app->setUserState($context . '.data', null); + break; + + default: + // Clear the record id and data from the session. + $this->releaseEditId($context, $recordId); + $app->setUserState($context . '.data', null); + + $returnUri = $this->input->post->get('return', null, 'base64'); + $returnUri = ! empty($returnUri) ? base64_decode(urldecode($returnUri)) : JUri::base(); + + // Redirect to the previous url + $this->setRedirect($returnUri); + break; + } + + $this->redirect(); + } + + /** + * Method to get the other modules in the same position + * + * @return string The data for the Ajax request. + * + * @since 3.6.3 + */ + public function orderPosition() + { + $app = JFactory::getApplication(); + + // Send json mime type. + $app->mimeType = 'application/json'; + $app->setHeader('Content-Type', $app->mimeType . '; charset=' . $app->charSet); + $app->sendHeaders(); + + // Check if user token is valid. + if ( ! JSession::checkToken('get')) + { + $app->enqueueMessage(JText::_('JINVALID_TOKEN'), 'error'); + echo new JResponseJson; + $app->close(); + } + + $jinput = $app->input; + $clientId = $jinput->getValue('client_id'); + $position = $jinput->getValue('position'); + + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('position, ordering, title') + ->from('#__modules') + ->where('client_id = ' . (int) $clientId . ' AND position = ' . $db->q($position)) + ->order('ordering'); + + $db->setQuery($query); + + try + { + $orders = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + throw new Exception($e->getMessage(), 500); + } + + $orders2 = []; + $n = count($orders); + + if ($n > 0) + { + for ($i = 0, $n; $i < $n; $i++) + { + if ( ! isset($orders2[$orders[$i]->position])) + { + $orders2[$orders[$i]->position] = 0; + } + + $orders2[$orders[$i]->position]++; + $ord = $orders2[$orders[$i]->position]; + $title = JText::sprintf('COM_MODULES_OPTION_ORDER_POSITION', $ord, htmlspecialchars($orders[$i]->title, ENT_QUOTES, 'UTF-8')); + + $html[] = $orders[$i]->position . ',' . $ord . ',' . $title; + } + } + else + { + $html[] = $position . ',' . 1 . ',' . JText::_('JNONE'); + } + + echo new JResponseJson($html); + $app->close(); + } +} diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/controllers/modules.php b/deployed/regularlabs/administrator/components/com_advancedmodules/controllers/modules.php new file mode 100644 index 00000000..cd0ee8bf --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/controllers/modules.php @@ -0,0 +1,107 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * Modules list controller class. + */ +class AdvancedModulesControllerModules extends JControllerAdmin +{ + /** + * @var string The prefix to use with controller messages. + */ + protected $text_prefix = 'COM_MODULES'; + + /** + * Method to clone an existing module. + * + * @return void + */ + public function duplicate() + { + // Check for request forgeries + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + $pks = $this->input->post->get('cid', [], 'array'); + JArrayHelper::toInteger($pks); + + try + { + if (empty($pks)) + { + throw new Exception(JText::_('COM_MODULES_ERROR_NO_MODULES_SELECTED')); + } + + $model = $this->getModel(); + $model->duplicate($pks); + $this->setMessage(JText::plural('COM_MODULES_N_MODULES_DUPLICATED', count($pks))); + } + catch (Exception $e) + { + throw new Exception($e->getMessage(), 500); + } + + $this->setRedirect('index.php?option=com_advancedmodules&view=modules'); + } + + /** + * Method to set the color of items + * + * @return void + */ + public function setcolor() + { + // Check for request forgeries + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + $pks = $this->input->post->get('cid', [], 'array'); + JArrayHelper::toInteger($pks); + + try + { + if (empty($pks)) + { + throw new Exception(JText::_('COM_MODULES_ERROR_NO_MODULES_SELECTED')); + } + $color = $this->input->post->get('setcolor', '', 'string'); + $model = $this->getModel(); + $model->setcolor($pks, $color); + } + catch (Exception $e) + { + throw new Exception($e->getMessage(), 500); + } + + $this->setRedirect('index.php?option=com_advancedmodules&view=modules'); + } + + /** + * Method to get a model object, loading it if required. + * + * @param string $name The model name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return object The model. + */ + public function getModel($name = 'Module', $prefix = 'AdvancedModulesModel', $config = ['ignore_request' => true]) + { + $model = parent::getModel($name, $prefix, $config); + + return $model; + } +} diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/helpers/html/modules.php b/deployed/regularlabs/administrator/components/com_advancedmodules/helpers/html/modules.php new file mode 100644 index 00000000..2c395f7e --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/helpers/html/modules.php @@ -0,0 +1,215 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * JHtml module helper class. + */ +abstract class JHtmlModules +{ + /** + * Builds an array of template options + * + * @param integer $clientId The client id. + * @param string $state The state of the template. + * + * @return array + */ + public static function templates($clientId = 0, $state = '') + { + $options = []; + $templates = ModulesHelper::getTemplates($clientId, $state); + + foreach ($templates as $template) + { + $options[] = JHtml::_('select.option', $template->element, $template->name); + } + + return $options; + } + + /** + * Builds an array of template type options + * + * @return array + */ + public static function types() + { + $options = []; + $options[] = JHtml::_('select.option', 'user', 'COM_MODULES_OPTION_POSITION_USER_DEFINED'); + $options[] = JHtml::_('select.option', 'template', 'COM_MODULES_OPTION_POSITION_TEMPLATE_DEFINED'); + + return $options; + } + + /** + * Builds an array of template state options + * + * @return array + */ + public static function templateStates() + { + $options = []; + $options[] = JHtml::_('select.option', '1', 'JENABLED'); + $options[] = JHtml::_('select.option', '0', 'JDISABLED'); + + return $options; + } + + /** + * Returns a published state on a grid + * + * @param integer $value The state value. + * @param integer $i The row index + * @param boolean $enabled An optional setting for access control on the action. + * @param string $checkbox An optional prefix for checkboxes. + * + * @return string The Html code + * + * @see JHtmlJGrid::state + * @since 1.7.1 + */ + public static function state($value, $i, $enabled = true, $checkbox = 'cb') + { + $states = [ + 'publish', + 'COM_MODULES_EXTENSION_UNPUBLISHED_DISABLED', + 'COM_MODULES_HTML_PUBLISH_DISABLED', + 'COM_MODULES_EXTENSION_UNPUBLISHED_DISABLED', + true, + 'unpublish', + 'unpublish', + ]; + + return JHtml::_('jgrid.state', $states, $value, $i, 'modules.', $enabled, true, $checkbox); + } + + /** + * Display a batch widget for the module position selector. + * + * @param integer $clientId The client ID. + * @param integer $state The state of the module (enabled, unenabled, trashed). + * @param string $selectedPosition The currently selected position for the module. + * + * @return string The necessary positions for the widget. + */ + + public static function positions($clientId, $state = 1, $selectedPosition = '') + { + require_once JPATH_ADMINISTRATOR . '/components/com_templates/helpers/templates.php'; + $templates = array_keys(ModulesHelper::getTemplates($clientId, $state)); + $templateGroups = []; + + // Add an empty value to be able to deselect a module position + $option = ModulesHelper::createOption(); + $templateGroups[''] = ModulesHelper::createOptionGroup('', [$option]); + + // Add positions from templates + $isTemplatePosition = false; + + foreach ($templates as $template) + { + $options = []; + + $positions = TemplatesHelper::getPositions($clientId, $template); + + if (is_array($positions)) + { + foreach ($positions as $position) + { + $text = ModulesHelper::getTranslatedModulePosition($clientId, $template, $position) . ' [' . $position . ']'; + $options[] = ModulesHelper::createOption($position, $text); + + if ( ! $isTemplatePosition && $selectedPosition === $position) + { + $isTemplatePosition = true; + } + } + + $options = JArrayHelper::sortObjects($options, 'text'); + } + + $templateGroups[$template] = ModulesHelper::createOptionGroup(ucfirst($template), $options); + } + + // Add custom position to options + $customGroupText = JText::_('COM_MODULES_CUSTOM_POSITION'); + + $editPositions = true; + $customPositions = ModulesHelper::getPositions($clientId, $editPositions); + $templateGroups[$customGroupText] = ModulesHelper::createOptionGroup($customGroupText, $customPositions); + + return $templateGroups; + } + + /** + * Get a select with the batch action options + * + * @return void + */ + public static function batchOptions() + { + // Create the copy/move options. + $options = [ + JHtml::_('select.option', 'c', JText::_('JLIB_HTML_BATCH_COPY')), + JHtml::_('select.option', 'm', JText::_('JLIB_HTML_BATCH_MOVE')), + ]; + + echo JHtml::_('select.radiolist', $options, 'batch[move_copy]', '', 'value', 'text', 'm'); + } + + /** + * Method to get the field options. + * + * @param integer $clientId The client ID + * + * @return array The field option objects. + */ + public static function positionList($clientId = 0) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('DISTINCT(position) as value') + ->select('position as text') + ->from($db->quoteName('#__modules')) + ->where($db->quoteName('client_id') . ' = ' . (int) $clientId) + ->order('position'); + + // Get the options. + $db->setQuery($query); + + try + { + $options = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + throw new Exception($e->getMessage(), 500); + } + + // Pop the first item off the array if it's blank + if (count($options)) + { + if (strlen($options[0]->text) < 1) + { + array_shift($options); + } + } + + return $options; + } +} diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/helpers/modules.php b/deployed/regularlabs/administrator/components/com_advancedmodules/helpers/modules.php new file mode 100644 index 00000000..1f002d7b --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/helpers/modules.php @@ -0,0 +1,329 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * Modules component helper. + */ +abstract class ModulesHelper +{ + /** + * Configure the Linkbar. + * + * @param string $vName The name of the active view. + * + * @return void + */ + public static function addSubmenu($vName) + { + // Not used in this component. + } + + /** + * Get a list of filter options for the state of a module. + * + * @return array An array of JHtmlOption elements. + */ + public static function getStateOptions() + { + // Build the filter options. + $options = []; + $options[] = JHtml::_('select.option', '1', JText::_('JPUBLISHED')); + $options[] = JHtml::_('select.option', '0', JText::_('JUNPUBLISHED')); + $options[] = JHtml::_('select.option', '-2', JText::_('JTRASHED')); + $options[] = JHtml::_('select.option', '*', JText::_('JALL')); + + return $options; + } + + /** + * Get a list of filter options for the application clients. + * + * @return array An array of JHtmlOption elements. + */ + public static function getClientOptions() + { + // Build the filter options. + $options = []; + $options[] = JHtml::_('select.option', '0', JText::_('JSITE')); + $options[] = JHtml::_('select.option', '1', JText::_('JADMINISTRATOR')); + + return $options; + } + + /** + * Get a list of modules positions + * + * @param integer $clientId Client ID + * @param boolean $editPositions Allow to edit the positions + * + * @return array A list of positions + */ + public static function getPositions($clientId, $editPositions = false) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('DISTINCT(position)') + ->from('#__modules') + ->where($db->quoteName('client_id') . ' = ' . (int) $clientId) + ->order('position'); + + $db->setQuery($query); + + try + { + $positions = $db->loadColumn(); + $positions = is_array($positions) ? $positions : []; + } + catch (RuntimeException $e) + { + throw new Exception($e->getMessage(), 500); + } + + // Build the list + $options = []; + + foreach ($positions as $position) + { + if ( ! $position && ! $editPositions) + { + $options[] = JHtml::_('select.option', 'none', ':: ' . JText::_('JNONE') . ' ::'); + continue; + } + + $options[] = JHtml::_('select.option', $position, $position); + } + + return $options; + } + + /** + * Return a list of templates + * + * @param integer $clientId Client ID + * @param string $state State + * @param string $template Template name + * + * @return array List of templates + */ + public static function getTemplates($clientId = 0, $state = '', $template = '') + { + $db = JFactory::getDbo(); + + // Get the database object and a new query object. + $query = $db->getQuery(true); + + // Build the query. + $query->select('element, name, enabled') + ->from('#__extensions') + ->where('client_id = ' . (int) $clientId) + ->where('type = ' . $db->quote('template')); + + if ($state != '') + { + $query->where('enabled = ' . $db->quote($state)); + } + + if ($template != '') + { + $query->where('element = ' . $db->quote($template)); + } + + // Set the query and load the templates. + $db->setQuery($query); + + return $db->loadObjectList('element'); + } + + /** + * Get a list of the unique modules installed in the client application. + * + * @param int $clientId The client id. + * + * @return array Array of unique modules + */ + public static function getModules($clientId) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('e.element AS value, e.name AS text') + ->from('#__extensions as e') + ->where('e.client_id = ' . (int) $clientId) + ->where('e.type = ' . $db->quote('module')) + ->join('LEFT', '#__modules as m ON m.module=e.element AND m.client_id=e.client_id') + ->where('m.module IS NOT NULL') + ->group('e.element, e.name'); + + $db->setQuery($query); + $modules = $db->loadObjectList(); + $lang = JFactory::getLanguage(); + + foreach ($modules as $i => $module) + { + $extension = $module->value; + $path = $clientId ? JPATH_ADMINISTRATOR : JPATH_SITE; + $source = $path . "/modules/$extension"; + $lang->load("$extension.sys", $path, null, false, true) + || $lang->load("$extension.sys", $source, null, false, true); + $modules[$i]->text = JText::_($module->text); + } + + JArrayHelper::sortObjects($modules, 'text', 1, true, true); + + return $modules; + } + + /** + * Get a list of the menu item assignment options for modules. + * + * @param int $clientId The client id. + * + * @return array + */ + public static function getMenuItemAssignmentOptions($clientId) + { + $options = []; + $options[] = JHtml::_('select.option', '0', JText::_('JALL')); + $options[] = JHtml::_('select.option', '-', JText::_('JNONE')); + + if ($clientId != 0) + { + return $options; + } + + $options[] = JHtml::_('select.option', '-1', JText::_('COM_MODULES_ASSIGNED_VARIES_EXCEPT')); + $options[] = JHtml::_('select.option', '-2', JText::_('COM_MODULES_ASSIGNED_VARIES_ONLY')); + + require_once realpath(JPATH_ADMINISTRATOR . '/components/com_menus/helpers/menus.php'); + $items = MenusHelper::getMenuLinks(); + + foreach ($items as $type) + { + $options[] = JHtml::_('select.option', '', $type->title); + + foreach ($type->links as $item) + { + $options[] = JHtml::_('select.option', $item->value, str_repeat('- ', $item->level) . $item->text); + } + + $options[] = JHtml::_('select.option', ''); + } + + return $options; + } + + /** + * Return a translated module position name + * + * @param integer $clientId Application client id 0: site | 1: admin + * @param string $template Template name + * @param string $position Position name + * + * @return string Return a translated position name + */ + public static function getTranslatedModulePosition($clientId, $template, $position) + { + // Template translation + $lang = JFactory::getLanguage(); + $path = $clientId ? JPATH_ADMINISTRATOR : JPATH_SITE; + + $loaded = $lang->getPaths('tpl_' . $template . '.sys'); + + // Only load the template's language file if it hasn't been already + if ( ! $loaded) + { + $lang->load('tpl_' . $template . '.sys', $path, null, false, false) + || $lang->load('tpl_' . $template . '.sys', $path . '/templates/' . $template, null, false, false) + || $lang->load('tpl_' . $template . '.sys', $path, $lang->getDefault(), false, false) + || $lang->load('tpl_' . $template . '.sys', $path . '/templates/' . $template, $lang->getDefault(), false, false); + } + + $langKey = strtoupper('TPL_' . $template . '_POSITION_' . $position); + $text = JText::_($langKey); + + // Avoid untranslated strings + if ( ! self::isTranslatedText($langKey, $text)) + { + // Modules component translation + $langKey = strtoupper('COM_MODULES_POSITION_' . $position); + $text = JText::_($langKey); + + // Avoid untranslated strings + if ( ! self::isTranslatedText($langKey, $text)) + { + // Try to humanize the position name + $text = ucfirst(preg_replace('/^' . $template . '\-/', '', $position)); + $text = ucwords(str_replace(['-', '_'], ' ', $text)); + } + } + + return $text; + } + + /** + * Check if the string was translated + * + * @param string $langKey Language file text key + * @param string $text The "translated" text to be checked + * + * @return boolean Return true for translated text + */ + public static function isTranslatedText($langKey, $text) + { + return $text !== $langKey; + } + + /** + * Create and return a new Option + * + * @param string $value The option value [optional] + * @param string $text The option text [optional] + * + * @return object The option as an object (stdClass instance) + */ + public static function createOption($value = '', $text = '') + { + if (empty($text)) + { + $text = $value; + } + + $option = (object) []; + $option->value = $value; + $option->text = $text; + + return $option; + } + + /** + * Create and return a new Option Group + * + * @param string $label Value and label for group [optional] + * @param array $options Array of options to insert into group [optional] + * + * @return array Return the new group as an array + */ + public static function createOptionGroup($label = '', $options = []) + { + $group = []; + $group['value'] = $label; + $group['text'] = $label; + $group['items'] = $options; + + return $group; + } +} diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/helpers/xml.php b/deployed/regularlabs/administrator/components/com_advancedmodules/helpers/xml.php new file mode 100644 index 00000000..3ce1e6e8 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/helpers/xml.php @@ -0,0 +1,60 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +JLog::add('ModulesHelperXML is deprecated. Do not use.', JLog::WARNING, 'deprecated'); + +/** + * Helper for parse XML module files + * @deprecated 3.2 Do not use. + */ +class ModulesHelperXML +{ + /** + * Parse the module XML file + * + * @param array &$rows XML rows + * + * @return void + * + * @deprecated 3.2 Do not use. + */ + public function parseXMLModuleFile(&$rows) + { + foreach ($rows as $i => $row) + { + if ($row->module == '') + { + $rows[$i]->name = 'custom'; + $rows[$i]->module = 'custom'; + $rows[$i]->descrip = 'Custom created module, using Module Manager New function'; + + continue; + } + + $data = JInstaller::parseXMLInstallFile($row->path . '/' . $row->file); + + if ($data['type'] != 'module') + { + continue; + } + + $rows[$i]->name = $data['name']; + $rows[$i]->descrip = $data['description']; + } + } +} diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/language/en-GB/en-GB.com_advancedmodules.ini b/deployed/regularlabs/administrator/components/com_advancedmodules/language/en-GB/en-GB.com_advancedmodules.ini new file mode 100644 index 00000000..bbf77a5c --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/language/en-GB/en-GB.com_advancedmodules.ini @@ -0,0 +1,83 @@ +;; @package Advanced Module Manager +;; @version 7.7.1 +;; +;; @author Peter van Westen +;; @link http://www.regularlabs.com +;; @copyright Copyright © 2018 Regular Labs All Rights Reserved +;; @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL +;; +;; @translate Want to help with translations? See: https://www.regularlabs.com/translate + +COM_ADVANCEDMODULES="Regular Labs - Advanced Module Manager" +COM_ADVANCEDMODULES_DESC="Advanced Module Manager - take control over modules in Joomla!" +COM_ADVANCEDMODULES_CONFIGURATION="Advanced Module Manager" +ADVANCED_MODULE_MANAGER="Advanced Module Manager" + +AMM_EXTENSION_CAN_NOT_FUNCTION="[[%1:extension name%]] cannot function." +AMM_REGULAR_LABS_LIBRARY_NOT_ENABLED="Regular Labs Library plugin is not enabled." +AMM_REGULAR_LABS_LIBRARY_NOT_INSTALLED="Regular Labs Library plugin is not installed." +AMM_REGULAR_LABS_LIBRARY_OUTDATED="Regular Labs Library plugin is outdated. Try to re-install [[%1:extension name%]]." + +JLIB_RULES_SETTING_NOTES="1. If you change the setting, it will apply to this component. Note that:
Inherited means that the permissions from global configuration and parent group will be used.
Denied means that no matter what the global configuration or parent group settings are, the group being edited cannot take this action on this component.
Allowed means that the group being edited will be able to take this action for this component (but if this is in conflict with the global configuration or parent group it will have no impact; a conflict will be indicated by Not Allowed (Locked) under Calculated Settings).
2. If you select a new setting, click Save to refresh the calculated settings." +JLIB_RULES_SETTING_NOTES_ITEM="1. If you change the setting, it will apply to this module. Note that:
Inherited means that the permissions from global configuration and parent group will be used.
Denied means that no matter what the global configuration or parent group settings are, the group being edited cannot take this action on this module.
Allowed means that the group being edited will be able to take this action for this module (but if this is in conflict with the global configuration or parent group it will have no impact; a conflict will be indicated by Not Allowed (Locked) under Calculated Settings).
2. If you select a new setting, click Save to refresh the calculated settings." + +AMM_ADVANCED_MODULE_MANAGER="Advanced Module Manager" +AMM_ASSIGNMENTS="Assignments" +AMM_COLOR="Colour" +AMM_COLOR_DESC="Give the module a colour in the module list. (This does not affect the output of the module in any way.)" +AMM_COLORS="Colours" +AMM_COLORS_DESC="A comma separated list of RGB colours to show in the colour picker." +AMM_DEFAULT_MENU_ASSIGNMENT="Default menu assignment" +AMM_DEFAULT_MENU_ASSIGNMENT_DESC="Select whether to set the menu assignment of new modules to all or no menu items." +AMM_DEFAULT_SETTINGS="Default settings" +AMM_DEFAULT_STATE="Default publish state" +AMM_DEFAULT_STATE_DESC="Select whether to set new modules to published or unpublished by default." +AMM_DESCRIPTION_DESC="An optional short description to display in the module list view." +AMM_DISABLE_ASSIGNMENT="If you do not want to use this assignment type on this website, you can disable assignments completely in the Advanced Module Manager options.
Disabled assignments will not show up in any modules.

Do you want to open the options?" +AMM_EDIT_MODULE="Edit Module" +AMM_EXTRA_COLUMN="Extra Column" +AMM_EXTRA_FIELD_LABEL="Label" +AMM_EXTRA_FIELD_LABEL_DESC="Define the label of the extra field. Leave empty to hide.

To give the label a tooltip, enter the text after a bar sign, like:
My Label|The description of this label" +AMM_HIDE_IF_EMPTY="Hide if empty" +AMM_HIDE_IF_EMPTY_DESC="Hides the module if its output is empty (to prevent module blocks with title but no content)." +AMM_LIST_TITLE="Module List Title" +AMM_LIST_TITLE_DESC="Select whether to show the core or Advanced Module Manager title in the module list." +AMM_MIRROR_MODULE="Same as other module" +AMM_MIRROR_MODULE_DESC="Select this to use the assignment settings of another module.

If Opposite is selected, the module will show up on all pages where the selected module will not show up." +AMM_MIRRORING_MODULE="Same as [[%1:module ID%]]" +AMM_MIRRORING_MODULE_OPPOSITE="Opposite of [[%1:module ID%]]" +AMM_MODULE="Module" +AMM_MODULE_DESC="Select the module you want to follow. This module will use the Assignment settings of the selected module." +AMM_MODULE_EDIT="Module: %s" +AMM_MODULE_INCOMPATIBLE="This module is probably incompatible with Advanced Module Manager.
The developers of this module have chosen to use non-standard elements and layout in the display of this page, which can cause issues with the extra features of Advanced Module Manager.

If you experience issues: [[%1:start link%]]Use the Joomla core module manager[[%2:end link%]]" +AMM_NAME_COLUMN="Name Column" +AMM_NOTES="Notes" +AMM_NOTES_DESC="Enter optional notes." +AMM_OPPOSITE="Opposite" +AMM_OPTION_SELECT_MENU_ID="- Select Menu Item Assignment -" +AMM_POST_HTML="HTML after" +AMM_POST_HTML_DESC="The entered html will be appended to the content of the module." +AMM_PRE_HTML="HTML before" +AMM_PRE_HTML_DESC="The entered html will be prepended to the content of the module." +AMM_REPLACE_URLS_FRONTEND="Enable Edit on Frontend" +AMM_REPLACE_URLS_FRONTEND_DESC="Select to make Advanced Module Manager handle the module edit links in the frontend. You can disable this if your template (framework) causes conflicts with Advanced Module Manager." +AMM_SHOW_CATEGORY="Show Category" +AMM_SHOW_CATEGORY_DESC="Enable to show the category column in the module list." +AMM_SHOW_COLOR="Show Colour" +AMM_SHOW_COLOR_DESC="Enable to show the colour column in the module list." +AMM_SHOW_DESCRIPTION_IN_LIST="Show Description" +AMM_SHOW_DESCRIPTION_IN_LIST_DESC="Select where to show the optional short description in the module list view." +AMM_SHOW_EXTRA_FIELDS="Show Extra Fields" +AMM_SHOW_EXTRA_FIELDS_DESC="Enable to show the custom extra fields.

You can define the labels of these fields. If no label is given, the field will not be shown.

The saved values can be used in the module chromes via values extra1-5:
$params->get('extra1')" +AMM_SHOW_HIDE_IF_EMPTY="Hide if empty" +AMM_SHOW_HIDE_IF_EMPTY_DESC="Enable to show the Hide if empty option" +AMM_SHOW_NOTES_TAB="Show Notes Tab" +AMM_SHOW_NOTES_TAB_DESC="Select to show an extra notes tab." +AMM_SHOW_PUBLISHING_OPTION="Show this publishing option in the module edit screen?" +AMM_SHOW_SWITCH="Show Switch" +AMM_SHOW_SWITCH_DESC="Select to show the link to switch to the Joomla core module manager (and back)." +AMM_SWITCH_TO_ADVANCED_MODULE_MANAGER="Switch to Advanced Module Manager" +AMM_SWITCH_TO_CORE="Switch to the Joomla core module manager" +AMM_USE_ADMIN_FROM_FRONTEND="Open Frontend Edit in Admin" +AMM_USE_ADMIN_FROM_FRONTEND_DESC="Select to make the frontend module edit links open in the admin side for administrators." +AMM_USE_CORE_RULES="Advanced Module Manager uses the core Module Manager permission rules." diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/language/en-GB/en-GB.com_advancedmodules.sys.ini b/deployed/regularlabs/administrator/components/com_advancedmodules/language/en-GB/en-GB.com_advancedmodules.sys.ini new file mode 100644 index 00000000..93e905a2 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/language/en-GB/en-GB.com_advancedmodules.sys.ini @@ -0,0 +1,13 @@ +;; @package Advanced Module Manager +;; @version 7.7.1 +;; +;; @author Peter van Westen +;; @link http://www.regularlabs.com +;; @copyright Copyright © 2018 Regular Labs All Rights Reserved +;; @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL +;; +;; @translate Want to help with translations? See: https://www.regularlabs.com/translate + +COM_ADVANCEDMODULES="Regular Labs - Advanced Module Manager" +COM_ADVANCEDMODULES_DESC="Advanced Module Manager - take control over modules in Joomla!" +ADVANCED_MODULE_MANAGER="Advanced Module Manager" diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/language/hu-HU/hu-HU.com_advancedmodules.ini b/deployed/regularlabs/administrator/components/com_advancedmodules/language/hu-HU/hu-HU.com_advancedmodules.ini new file mode 100644 index 00000000..367b9e94 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/language/hu-HU/hu-HU.com_advancedmodules.ini @@ -0,0 +1,85 @@ +;; @package Advanced Module Manager +;; @version 7.7.1 +;; +;; @author Peter van Westen +;; @link http://www.regularlabs.com +;; @copyright Copyright © 2018 Regular Labs All Rights Reserved +;; @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL +;; +;; @translate Want to help with translations? See: https://www.regularlabs.com/translate +;; +;; @translation Fordította: Csontos Balázs Joomla! Magyarország (joomlacms.hu) + +COM_ADVANCEDMODULES="Regular Labs - Advanced Module Manager" +COM_ADVANCEDMODULES_DESC="Advanced Module Manager - kibővített beállítások Joomla! modulok számára" +COM_ADVANCEDMODULES_CONFIGURATION="Advanced Module Manager" +ADVANCED_MODULE_MANAGER="Advanced Module Manager" + +AMM_EXTENSION_CAN_NOT_FUNCTION="[[%1:extension name%]] nem működik." +AMM_REGULAR_LABS_LIBRARY_NOT_ENABLED="A Regular Labs keretrendszer beépülő-modul nincs engedélyezve." +AMM_REGULAR_LABS_LIBRARY_NOT_INSTALLED="A Regular Labs keretrendszer beépülő-modul nincs telepítve." +; AMM_REGULAR_LABS_LIBRARY_OUTDATED="Regular Labs Library plugin is outdated. Try to re-install [[%1:extension name%]]." + +; JLIB_RULES_SETTING_NOTES="1. If you change the setting, it will apply to this component. Note that:
Inherited means that the permissions from global configuration and parent group will be used.
Denied means that no matter what the global configuration or parent group settings are, the group being edited cannot take this action on this component.
Allowed means that the group being edited will be able to take this action for this component (but if this is in conflict with the global configuration or parent group it will have no impact; a conflict will be indicated by Not Allowed (Locked) under Calculated Settings).
2. If you select a new setting, click Save to refresh the calculated settings." +; JLIB_RULES_SETTING_NOTES_ITEM="1. If you change the setting, it will apply to this module. Note that:
Inherited means that the permissions from global configuration and parent group will be used.
Denied means that no matter what the global configuration or parent group settings are, the group being edited cannot take this action on this module.
Allowed means that the group being edited will be able to take this action for this module (but if this is in conflict with the global configuration or parent group it will have no impact; a conflict will be indicated by Not Allowed (Locked) under Calculated Settings).
2. If you select a new setting, click Save to refresh the calculated settings." + +AMM_ADVANCED_MODULE_MANAGER="Advanced Module Manager" +; AMM_ASSIGNMENTS="Assignments" +AMM_COLOR="Szín" +AMM_COLOR_DESC="Adj a modulnak egy színt a modulok listája nézethez. (Ez nincs semmiféle hatással a modul megjelenésére.)" +; AMM_COLORS="Colours" +; AMM_COLORS_DESC="A comma separated list of RGB colours to show in the colour picker." +; AMM_DEFAULT_MENU_ASSIGNMENT="Default menu assignment" +; AMM_DEFAULT_MENU_ASSIGNMENT_DESC="Select whether to set the menu assignment of new modules to all or no menu items." +AMM_DEFAULT_SETTINGS="Alapértelmezett beállítások" +; AMM_DEFAULT_STATE="Default publish state" +; AMM_DEFAULT_STATE_DESC="Select whether to set new modules to published or unpublished by default." +; AMM_DESCRIPTION_DESC="An optional short description to display in the module list view." +; AMM_DISABLE_ASSIGNMENT="If you do not want to use this assignment type on this website, you can disable assignments completely in the Advanced Module Manager options.
Disabled assignments will not show up in any modules.

Do you want to open the options?" +AMM_EDIT_MODULE="Modul szerkesztése" +AMM_EXTRA_COLUMN="Extra oszlop" +AMM_EXTRA_FIELD_LABEL="Címke" +AMM_EXTRA_FIELD_LABEL_DESC="Add meg az extra mező címkéjét. Elrejtéshez hagyd üresen.

Az eszköztipp címkéjének megadásához a szöveget írd egy függőlegesvonal után, így:
Saját címke|Ennek a címkének a leírása" +AMM_HIDE_IF_EMPTY="Elrejtés ha üres" +AMM_HIDE_IF_EMPTY_DESC="Modul elrejtése, ha annak kimenete üres (címmel rendelkező, de tartalom nélküli blokkok megjelenítésének megelőzéséhez)." +; AMM_LIST_TITLE="Module List Title" +; AMM_LIST_TITLE_DESC="Select whether to show the core or Advanced Module Manager title in the module list." +; AMM_MIRROR_MODULE="Same as other module" +; AMM_MIRROR_MODULE_DESC="Select this to use the assignment settings of another module.

If Opposite is selected, the module will show up on all pages where the selected module will not show up." +; AMM_MIRRORING_MODULE="Same as [[%1:module ID%]]" +; AMM_MIRRORING_MODULE_OPPOSITE="Opposite of [[%1:module ID%]]" +AMM_MODULE="Modul" +; AMM_MODULE_DESC="Select the module you want to follow. This module will use the Assignment settings of the selected module." +AMM_MODULE_EDIT="Modul: %s" +; AMM_MODULE_INCOMPATIBLE="This module is probably incompatible with Advanced Module Manager.
The developers of this module have chosen to use non-standard elements and layout in the display of this page, which can cause issues with the extra features of Advanced Module Manager.

If you experience issues: [[%1:start link%]]Use the Joomla core module manager[[%2:end link%]]" +AMM_NAME_COLUMN="Oszlop neve" +AMM_NOTES="Megjegyzések" +; AMM_NOTES_DESC="Enter optional notes." +; AMM_OPPOSITE="Opposite" +; AMM_OPTION_SELECT_MENU_ID="- Select Menu Item Assignment -" +; AMM_POST_HTML="HTML after" +; AMM_POST_HTML_DESC="The entered html will be appended to the content of the module." +; AMM_PRE_HTML="HTML before" +; AMM_PRE_HTML_DESC="The entered html will be prepended to the content of the module." +; AMM_REPLACE_URLS_FRONTEND="Enable Edit on Frontend" +; AMM_REPLACE_URLS_FRONTEND_DESC="Select to make Advanced Module Manager handle the module edit links in the frontend. You can disable this if your template (framework) causes conflicts with Advanced Module Manager." +AMM_SHOW_CATEGORY="Kategória megjelenítése" +; AMM_SHOW_CATEGORY_DESC="Enable to show the category column in the module list." +AMM_SHOW_COLOR="Színek megjelenítése" +AMM_SHOW_COLOR_DESC="Szín oszlop megjelenítése a modulok listájánál" +; AMM_SHOW_DESCRIPTION_IN_LIST="Show Description" +; AMM_SHOW_DESCRIPTION_IN_LIST_DESC="Select where to show the optional short description in the module list view." +AMM_SHOW_EXTRA_FIELDS="Extra mezők megjelenítése" +; AMM_SHOW_EXTRA_FIELDS_DESC="Enable to show the custom extra fields.

You can define the labels of these fields. If no label is given, the field will not be shown.

The saved values can be used in the module chromes via values extra1-5:
$params->get('extra1')" +AMM_SHOW_HIDE_IF_EMPTY="Elrejtés ha üres" +; AMM_SHOW_HIDE_IF_EMPTY_DESC="Enable to show the Hide if empty option" +; AMM_SHOW_NOTES_TAB="Show Notes Tab" +; AMM_SHOW_NOTES_TAB_DESC="Select to show an extra notes tab." +; AMM_SHOW_PUBLISHING_OPTION="Show this publishing option in the module edit screen?" +AMM_SHOW_SWITCH="Kapcsoló megjelenítése" +; AMM_SHOW_SWITCH_DESC="Select to show the link to switch to the Joomla core module manager (and back)." +AMM_SWITCH_TO_ADVANCED_MODULE_MANAGER="Váltás az Advanced Module Manager-re" +; AMM_SWITCH_TO_CORE="Switch to the Joomla core module manager" +; AMM_USE_ADMIN_FROM_FRONTEND="Open Frontend Edit in Admin" +; AMM_USE_ADMIN_FROM_FRONTEND_DESC="Select to make the frontend module edit links open in the admin side for administrators." +; AMM_USE_CORE_RULES="Advanced Module Manager uses the core Module Manager permission rules." diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/language/hu-HU/hu-HU.com_advancedmodules.sys.ini b/deployed/regularlabs/administrator/components/com_advancedmodules/language/hu-HU/hu-HU.com_advancedmodules.sys.ini new file mode 100644 index 00000000..20829d64 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/language/hu-HU/hu-HU.com_advancedmodules.sys.ini @@ -0,0 +1,15 @@ +;; @package Advanced Module Manager +;; @version 7.7.1 +;; +;; @author Peter van Westen +;; @link http://www.regularlabs.com +;; @copyright Copyright © 2018 Regular Labs All Rights Reserved +;; @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL +;; +;; @translate Want to help with translations? See: https://www.regularlabs.com/translate +;; +;; @translation Fordította: Csontos Balázs Joomla! Magyarország (joomlacms.hu) + +COM_ADVANCEDMODULES="Regular Labs - Advanced Module Manager" +COM_ADVANCEDMODULES_DESC="Advanced Module Manager - kibővített beállítások Joomla! modulok számára" +ADVANCED_MODULE_MANAGER="Advanced Module Manager" diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/layouts/joomla/edit/frontediting_modules.php b/deployed/regularlabs/administrator/components/com_advancedmodules/layouts/joomla/edit/frontediting_modules.php new file mode 100644 index 00000000..e0034f66 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/layouts/joomla/edit/frontediting_modules.php @@ -0,0 +1,65 @@ +]*class="[^"]* jmoddiv"/', $moduleHtml)) +{ + // Module has already module edit button: + return; +} + +// Add css class jmoddiv and data attributes for module-editing URL and for the tooltip: +$editUrl = JUri::base() . 'administrator/index.php?option=com_advancedmodules&view=module&layout=edit&id=' . (int) $mod->id; + +$title = preg_replace('#\{.*?\}#', '', $mod->title); +$position = sprintf(JText::_('JLIB_HTML_EDIT_MODULE_IN_POSITION'), $position); + +$tooltip = JHtml::tooltipText( + JText::_('JLIB_HTML_EDIT_MODULE'), + htmlspecialchars($title) . '
' . htmlspecialchars($position), + 0 +); + +// By itself, adding class jmoddiv and data attributes for the url and tooltip: +$replace = '\\1 jmoddiv" data-jmodediturl="' . $editUrl . '" data-jmodtip="' . $tooltip . '"'; + +// And if menu editing is enabled and allowed and it's a menu module, add data attributes for menu editing: +if ($menusEditing && $mod->module == 'mod_menu') +{ + $replace .= ' data-jmenuedittip="' . JHtml::tooltipText('JLIB_HTML_EDIT_MENU_ITEM', 'JLIB_HTML_EDIT_MENU_ITEM_ID') . '"'; +} + +// Add class, editing URL and tooltip, and if module of type menu, also the tooltip for editing the menu item: +$count = 0; +$moduleHtml = preg_replace( +// Replace first tag of module with a class + '/^(\s*<(?:div|span|nav|ul|ol|h\d) [^>]*class="[^"]*)"/', + $replace, + $moduleHtml, + 1, + $count +); + +if ($count) +{ + // Load once booststrap tooltip and add stylesheet and javascript to head: + JHtml::_('bootstrap.tooltip'); + JHtml::_('bootstrap.popover'); + + JHtml::_('stylesheet', 'system/frontediting.css', [], true); + JHtml::_('script', 'system/frontediting.js', false, true); +} diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/layouts/joomla/edit/params.php b/deployed/regularlabs/administrator/components/com_advancedmodules/layouts/joomla/edit/params.php new file mode 100644 index 00000000..c9b434e4 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/layouts/joomla/edit/params.php @@ -0,0 +1,133 @@ +getForm(); +$fieldSets = $form->getFieldsets(); + +if (empty($fieldSets)) +{ + return; +} + +$ignoreFieldsets = $displayData->get('ignore_fieldsets') ?: array(); +$ignoreFields = $displayData->get('ignore_fields') ?: array(); +$extraFields = $displayData->get('extra_fields') ?: array(); +$tabName = $displayData->get('tab_name') ?: 'myTab'; + +if (!empty($displayData->hiddenFieldsets)) +{ + // These are required to preserve data on save when fields are not displayed. + $hiddenFieldsets = $displayData->hiddenFieldsets ?: array(); +} + +if (!empty($displayData->configFieldsets)) +{ + // These are required to configure showing and hiding fields in the editor. + $configFieldsets = $displayData->configFieldsets ?: array(); +} + +// Handle the hidden fieldsets when show_options is set false +if (!$displayData->get('show_options', 1)) +{ + // The HTML buffer + $html = array(); + + // Hide the whole buffer + $html[] = '
'; + + // Loop over the fieldsets + foreach ($fieldSets as $name => $fieldSet) + { + // Check if the fieldset should be ignored + if (in_array($name, $ignoreFieldsets, true)) + { + continue; + } + + // If it is a hidden fieldset, render the inputs + if (in_array($name, $hiddenFieldsets)) + { + // Loop over the fields + foreach ($form->getFieldset($name) as $field) + { + // Add only the input on the buffer + $html[] = $field->input; + } + + // Make sure the fieldset is not rendered twice + $ignoreFieldsets[] = $name; + } + + // Check if it is the correct fieldset to ignore + if (strpos($name, 'basic') === 0) + { + // Ignore only the fieldsets which are defined by the options not the custom fields ones + $ignoreFieldsets[] = $name; + } + } + + // Close the container + $html[] = '
'; + + // Echo the hidden fieldsets + echo implode('', $html); +} + +// Loop again over the fieldsets +foreach ($fieldSets as $name => $fieldSet) +{ + // Ensure any fieldsets we don't want to show are skipped (including repeating formfield fieldsets) + if ((isset($fieldSet->repeat) && $fieldSet->repeat === true) + || in_array($name, $ignoreFieldsets) + || (!empty($configFieldsets) && in_array($name, $configFieldsets, true)) + || (!empty($hiddenFieldsets) && in_array($name, $hiddenFieldsets, true)) + ) + { + continue; + } + + // Determine the label + if (!empty($fieldSet->label)) + { + $label = JText::_($fieldSet->label); + } + else + { + $label = strtoupper('JGLOBAL_FIELDSET_' . $name); + if (JText::_($label) === $label) + { + $label = strtoupper('COM_MODULES_' . $name . '_FIELDSET_LABEL'); + } + $label = JText::_($label); + } + + // Start the tab + echo JHtml::_('bootstrap.addTab', $tabName, 'attrib-' . $name, $label); + + // Include the description when available + if (isset($fieldSet->description) && trim($fieldSet->description)) + { + echo '

' . $this->escape(JText::_($fieldSet->description)) . '

'; + } + + // The name of the fieldset to render + $displayData->fieldset = $name; + + // Force to show the options + $displayData->showOptions = true; + + // Render the fieldset + echo JLayoutHelper::render('joomla.edit.fieldset', $displayData); + + // End the tab + echo JHtml::_('bootstrap.endTab'); +} diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/layouts/joomla/searchtools/default.php b/deployed/regularlabs/administrator/components/com_advancedmodules/layouts/joomla/searchtools/default.php new file mode 100644 index 00000000..19113a4c --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/layouts/joomla/searchtools/default.php @@ -0,0 +1,50 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('JPATH_BASE') or die; + +use RegularLabs\Library\Document as RL_Document; + +$data = $displayData; + +// Receive overridable options +$data['options'] = ! empty($data['options']) ? $data['options'] : []; + +if ($data['view'] instanceof AdvancedModulesViewModules && JFactory::getApplication()->input->get('layout', '', 'cmd') !== 'modal') +{ + RL_Document::styleDeclaration(" + /* Fixed filter field in search bar */ + .js-stools .js-stools-client_id { + float: left; + margin-right: 10px; + min-width: 220px; + } + html[dir=rtl] .js-stools .js-stools-client_id { + float: right; + margin-left: 10px + margin-right: 0; + } + .js-stools .js-stools-container-bar .js-stools-field-filter .chzn-container { + padding: 3px 0; + } + "); + + // Client selector doesn't have to activate the filter bar. + unset($data['view']->activeFilters['client_id']); +} + +// Display the main joomla layout. +include JPATH_SITE . '/layouts/joomla/searchtools/default.php'; diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/layouts/joomla/searchtools/default/bar.php b/deployed/regularlabs/administrator/components/com_advancedmodules/layouts/joomla/searchtools/default/bar.php new file mode 100644 index 00000000..258432fe --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/layouts/joomla/searchtools/default/bar.php @@ -0,0 +1,33 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('JPATH_BASE') or die; + +$data = $displayData; + +if ($data['view'] instanceof AdvancedModulesViewModules && JFactory::getApplication()->input->get('layout', '', 'cmd') !== 'modal') +{ + // Add the client selector before the form filters. + $clientIdField = $data['view']->filterForm->getField('client_id'); + ?> +
+ input; ?> +
+ 'none']); diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/layouts/joomla/searchtools/grid/sort.php b/deployed/regularlabs/administrator/components/com_advancedmodules/layouts/joomla/searchtools/grid/sort.php new file mode 100644 index 00000000..a169d2a2 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/layouts/joomla/searchtools/grid/sort.php @@ -0,0 +1,21 @@ +tip ? $data->tip : $data->title), JText::_('JGLOBAL_CLICK_TO_SORT_THIS_COLUMN'), 0); +JHtml::_('bootstrap.tooltip'); +?> + + icon)) : ?> + title)) : ?>title); ?> + order == $data->selected) : ?> + diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/layouts/toolbar/cancelselect.php b/deployed/regularlabs/administrator/components/com_advancedmodules/layouts/toolbar/cancelselect.php new file mode 100644 index 00000000..7eaf1956 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/layouts/toolbar/cancelselect.php @@ -0,0 +1,23 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +$text = JText::_('JTOOLBAR_CANCEL'); +?> + diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/layouts/toolbar/newmodule.php b/deployed/regularlabs/administrator/components/com_advancedmodules/layouts/toolbar/newmodule.php new file mode 100644 index 00000000..4dff9e47 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/layouts/toolbar/newmodule.php @@ -0,0 +1,24 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +$text = JText::_('JTOOLBAR_NEW'); +?> + diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/models/fields/modulesmenuid.php b/deployed/regularlabs/administrator/components/com_advancedmodules/models/fields/modulesmenuid.php new file mode 100644 index 00000000..5b3168ce --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/models/fields/modulesmenuid.php @@ -0,0 +1,34 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('JPATH_BASE') or die; + +JFormHelper::loadFieldClass('list'); + +require_once __DIR__ . '/../../helpers/modules.php'; + +class JFormFieldModulesMenuId extends JFormFieldList +{ + protected $type = 'ModulesMenuId'; + + public function getOptions() + { + $clientId = JFactory::getApplication()->input->get('client_id', 0, 'int'); + $options = ModulesHelper::getMenuItemAssignmentOptions($clientId); + + return array_merge(parent::getOptions(), $options); + } +} diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/models/fields/modulesmodule.php b/deployed/regularlabs/administrator/components/com_advancedmodules/models/fields/modulesmodule.php new file mode 100644 index 00000000..04a7f657 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/models/fields/modulesmodule.php @@ -0,0 +1,48 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('JPATH_BASE') or die; + +JFormHelper::loadFieldClass('list'); + +require_once __DIR__ . '/../../helpers/modules.php'; + +/** + * ModulesPosition Field class for the Joomla Framework. + */ +class JFormFieldModulesModule extends JFormFieldList +{ + /** + * The form field type. + * + * @var string + * @since 3.4.2 + */ + protected $type = 'ModulesModule'; + + /** + * Method to get the field options. + * + * @return array The field option objects. + */ + public function getOptions() + { + $clientId = JFactory::getApplication()->input->get('client_id', 0, 'int'); + $options = ModulesHelper::getModules($clientId); + + return array_merge(parent::getOptions(), $options); + } +} diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/models/fields/modulesposition.php b/deployed/regularlabs/administrator/components/com_advancedmodules/models/fields/modulesposition.php new file mode 100644 index 00000000..a010ca77 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/models/fields/modulesposition.php @@ -0,0 +1,48 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('JPATH_BASE') or die; + +JFormHelper::loadFieldClass('list'); + +require_once __DIR__ . '/../../helpers/modules.php'; + +/** + * ModulesPosition Field class for the Joomla Framework. + */ +class JFormFieldModulesPosition extends JFormFieldList +{ + /** + * The form field type. + * + * @var string + * @since 3.4.2 + */ + protected $type = 'ModulesPosition'; + + /** + * Method to get the field options. + * + * @return array The field option objects. + */ + public function getOptions() + { + $clientId = JFactory::getApplication()->input->get('client_id', 0, 'int'); + $options = ModulesHelper::getPositions($clientId); + + return array_merge(parent::getOptions(), $options); + } +} diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/models/forms/advanced.xml b/deployed/regularlabs/administrator/components/com_advancedmodules/models/forms/advanced.xml new file mode 100644 index 00000000..89e897a4 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/models/forms/advanced.xml @@ -0,0 +1,48 @@ + +
+ +
+ + + + + + + + + + +
+
+
diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/models/forms/filter_modules.xml b/deployed/regularlabs/administrator/components/com_advancedmodules/models/forms/filter_modules.xml new file mode 100644 index 00000000..ca036904 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/models/forms/filter_modules.xml @@ -0,0 +1,130 @@ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/models/forms/module.xml b/deployed/regularlabs/administrator/components/com_advancedmodules/models/forms/module.xml new file mode 100644 index 00000000..f184ac41 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/models/forms/module.xml @@ -0,0 +1,134 @@ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/models/forms/moduleadmin.xml b/deployed/regularlabs/administrator/components/com_advancedmodules/models/forms/moduleadmin.xml new file mode 100644 index 00000000..aa1bd77d --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/models/forms/moduleadmin.xml @@ -0,0 +1,136 @@ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/models/module.php b/deployed/regularlabs/administrator/components/com_advancedmodules/models/module.php new file mode 100644 index 00000000..cb9bb91d --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/models/module.php @@ -0,0 +1,1795 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use RegularLabs\Library\Date as RL_Date; +use RegularLabs\Library\Parameters as RL_Parameters; +use RegularLabs\Library\RegEx as RL_RegEx; +use RegularLabs\Library\StringHelper as RL_String; + +/** + * Module model. + */ +class AdvancedModulesModelModule extends JModelAdmin +{ + /** + * The type alias for this content type. + * + * @var string + * @since 3.4 + */ + public $typeAlias = 'com_modules.module'; + + /** + * @var string The prefix to use with controller messages. + * @since 1.6 + */ + protected $text_prefix = 'COM_MODULES'; + + /** + * @var string The help screen key for the module. + * @since 1.6 + */ + protected $helpKey = 'JHELP_EXTENSIONS_MODULE_MANAGER_EDIT'; + + /** + * @var string The help screen base URL for the module. + * @since 1.6 + */ + protected $helpURL; + + /** + * Batch copy/move command. If set to false, + * the batch copy/move command is not supported + * + * @var string + */ + protected $batch_copymove = 'position_id'; + + /** + * Allowed batch commands + * + * @var array + */ + protected $batch_commands = [ + 'assetgroup_id' => 'batchAccess', + 'language_id' => 'batchLanguage', + ]; + + /** + * Constructor. + * + * @param array $config An optional associative array of configuration settings. + */ + public function __construct($config = []) + { + $config = array_merge( + [ + 'event_after_delete' => 'onExtensionAfterDelete', + 'event_after_save' => 'onExtensionAfterSave', + 'event_before_delete' => 'onExtensionBeforeDelete', + 'event_before_save' => 'onExtensionBeforeSave', + 'events_map' => [ + 'save' => 'extension', + 'delete' => 'extension', + ], + ], $config + ); + + parent::__construct($config); + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + */ + protected function populateState() + { + $app = JFactory::getApplication('administrator'); + + // Load the User state. + $pk = $app->input->getInt('id'); + + if ( ! $pk) + { + if ($extensionId = (int) $app->getUserState('com_advancedmodules.add.module.extension_id')) + { + $this->setState('extension.id', $extensionId); + } + } + + $this->setState('module.id', $pk); + + // Load the parameters. + $params = JComponentHelper::getParams('com_advancedmodules'); + $this->setState('params', $params); + + $this->getConfig(); + } + + /** + * Method to perform batch operations on a set of modules. + * + * @param array $commands An array of commands to perform. + * @param array $pks An array of item ids. + * @param array $contexts An array of item contexts. + * + * @return boolean Returns true on success, false on failure. + */ + public function batch($commands, $pks, $contexts) + { + // Sanitize user ids. + $pks = array_unique($pks); + JArrayHelper::toInteger($pks); + + // Remove any values of zero. + if (array_search(0, $pks, true)) + { + unset($pks[array_search(0, $pks, true)]); + } + + if (empty($pks)) + { + $this->setError(JText::_('JGLOBAL_NO_ITEM_SELECTED')); + + return false; + } + + $done = false; + + if ( ! empty($commands['position_id'])) + { + $cmd = JArrayHelper::getValue($commands, 'move_copy', 'c'); + + if ($cmd == 'm' && ! $this->batchMove($commands['position_id'], $pks, $contexts)) + { + return false; + } + + if ($cmd == 'c') + { + $result = $this->batchCopy($commands['position_id'], $pks, $contexts); + if ( ! is_array($result)) + { + return false; + } + + $pks = $result; + } + + $done = true; + } + + if ( ! empty($commands['assetgroup_id'])) + { + if ( ! $this->batchAccess($commands['assetgroup_id'], $pks, $contexts)) + { + return false; + } + + $done = true; + } + + if ( ! empty($commands['language_id'])) + { + if ( ! $this->batchLanguage($commands['language_id'], $pks, $contexts)) + { + return false; + } + + $done = true; + } + + if ( ! $done) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_INSUFFICIENT_BATCH_INFORMATION')); + + return false; + } + + // Clear the cache + $this->cleanCache(); + + return true; + } + + /** + * Batch language changes for a group of rows. + * + * @param string $value The new value matching a language. + * @param array $pks An array of row IDs. + * @param array $contexts An array of item contexts. + * + * @return boolean True if successful, false otherwise and internal error is set. + */ + protected function batchLanguage($value, $pks, $contexts) + { + // Set the variables + $user = JFactory::getUser(); + $db = $this->getDbo(); + $table = $this->getTable(); + $table_adv = JTable::getInstance('AdvancedModules', 'AdvancedModulesTable'); + + foreach ($pks as $pk) + { + if ( ! $user->authorise('core.edit', $contexts[$pk])) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); + + return false; + } + + $table->reset(); + $table->load($pk); + $table->language = $value; + + if ( ! $table->store()) + { + $this->setError($table->getError()); + + return false; + } + + if ($table->id && ! $table_adv->load($table->id)) + { + $table_adv->moduleid = $table->id; + $db->insertObject($table_adv->getTableName(), $table_adv, $table_adv->getKeyName()); + } + + if ($table_adv->load($pk, true)) + { + $table_adv->moduleid = $table->id; + + $params = json_decode($table_adv->params); + if (is_null($params)) + { + $params = (object) []; + } + + $params->assignto_languages = 0; + $params->assignto_languages_selection = []; + if ($value != '*') + { + $params->assignto_languages = 1; + $params->assignto_languages_selection = [$value]; + } + + $table_adv->params = json_encode($params); + + if ( ! $table_adv->check() || ! $table_adv->store()) + { + $this->setError($table_adv->getError()); + + return false; + } + } + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + + /** + * Batch copy modules to a new position or current. + * + * @param integer $value The new value matching a module position. + * @param array $pks An array of row IDs. + * @param array $contexts An array of item contexts. + * + * @return boolean True if successful, false otherwise and internal error is set. + */ + protected function batchCopy($value, $pks, $contexts) + { + // Set the variables + $user = JFactory::getUser(); + $db = $this->getDbo(); + $query = $db->getQuery(true); + $table = $this->getTable(); + $table_adv = JTable::getInstance('AdvancedModules', 'AdvancedModulesTable'); + $newIds = []; + + foreach ($pks as $pk) + { + if ( ! $user->authorise('core.create', 'com_modules')) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE')); + + return false; + } + + $table->reset(); + $table->load($pk); + + // Set the new position + switch ($value) + { + case 'noposition': + $position = ''; + break; + + case 'nochange': + $position = $table->position; + break; + + default: + $position = $value; + break; + } + + $table->position = $position; + + // Alter the title if necessary + $data = $this->generateNewTitle(0, $table->title, $table->position); + $table->title = $data[0]; + + // Reset the ID because we are making a copy + $table->id = 0; + + // Unpublish the new module + $table->published = 0; + + if ( ! $table->store()) + { + $this->setError($table->getError()); + + return false; + } + + // Get the new item ID + $newId = (int) $table->get('id'); + + // Add the new ID to the array + $newIds[$pk] = $newId; + + // Now we need to handle the module assignments + $query->clear() + ->select('m.menuid') + ->from('#__modules_menu AS m') + ->where('m.moduleid = ' . (int) $pk); + $db->setQuery($query); + $menus = $db->loadColumn(); + + // Insert the new records into the table + foreach ($menus as $menu) + { + $query->clear() + ->insert('#__modules_menu') + ->columns([$db->quoteName('moduleid'), $db->quoteName('menuid')]) + ->values($newId . ', ' . $menu); + $db->setQuery($query); + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + throw new Exception($e->getMessage(), 500); + } + } + + if ($table->id && ! $table_adv->load($table->id)) + { + $table_adv->moduleid = $table->id; + $db->insertObject($table_adv->getTableName(), $table_adv, $table_adv->getKeyName()); + } + + if ( ! $table_adv->load($pk, true)) + { + continue; + } + + $table_adv->moduleid = $table->id; + + $rules = JAccess::getAssetRules('com_modules.module.' . $pk); + $table_adv->setRules($rules); + + if ( ! $table_adv->check() || ! $table_adv->store()) + { + $this->setError($table_adv->getError()); + + return false; + } + } + + // Clean the cache + $this->cleanCache(); + + return $newIds; + } + + /** + * Batch move modules to a new position or current. + * + * @param integer $value The new value matching a module position. + * @param array $pks An array of row IDs. + * @param array $contexts An array of item contexts. + * + * @return boolean True if successful, false otherwise and internal error is set. + */ + protected function batchMove($value, $pks, $contexts) + { + // Set the variables + $user = JFactory::getUser(); + $table = $this->getTable(); + + foreach ($pks as $pk) + { + if ( ! $user->authorise('core.edit', 'com_modules')) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); + + return false; + } + + $table->reset(); + $table->load($pk); + + // Set the new position + switch ($value) + { + case 'noposition': + $position = ''; + break; + + case 'nochange': + $position = $table->position; + break; + + default: + $position = $value; + break; + } + + $table->position = $position; + + if ( ! $table->store()) + { + $this->setError($table->getError()); + + return false; + } + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + + /** + * Method to test whether a record can have its state edited. + * + * @param object $record A record object. + * + * @return boolean True if allowed to change the state of the record. Defaults to the permission set in the component. + */ + protected function canEditState($record) + { + $user = JFactory::getUser(); + + // Check for existing module. + if ( ! empty($record->id)) + { + return $user->authorise('core.edit.state', 'com_modules.module.' . (int) $record->id); + } + + // Default to component settings if module not known. + return parent::canEditState('com_modules'); + } + + /** + * Method to delete rows. + * + * @param array &$pks An array of item ids. + * + * @return boolean Returns true on success, false on failure. + * @throws Exception + */ + public function delete(&$pks) + { + $dispatcher = JEventDispatcher::getInstance(); + $pks = (array) $pks; + $user = JFactory::getUser(); + $table = $this->getTable(); + $db = $this->getDbo(); + $query = $db->getQuery(true); + $context = $this->option . '.' . $this->name; + + // Include the plugins for the on delete events. + JPluginHelper::importPlugin($this->events_map['delete']); + + // Iterate the items to delete each one. + foreach ($pks as $pk) + { + if ( ! $table->load($pk)) + { + throw new Exception($table->getError()); + } + + // Access checks. + if ( ! $user->authorise('core.delete', 'com_modules.module.' . (int) $pk) || $table->published != -2) + { + throw new Exception(JText::_('JERROR_CORE_DELETE_NOT_PERMITTED'), 403); + } + + // Trigger the before delete event. + $result = $dispatcher->trigger($this->event_before_delete, [$context, $table]); + + if (in_array(false, $result, true) || ! $table->delete($pk)) + { + throw new Exception($table->getError()); + } + + // Delete the menu assignments + $query->clear() + ->delete('#__modules_menu') + ->where('moduleid=' . (int) $pk); + $db->setQuery($query); + $db->execute(); + + $query->clear() + ->delete('#__advancedmodules') + ->where('moduleid=' . (int) $pk); + $db->setQuery($query); + $db->execute(); + + // delete asset + $query->clear() + ->delete('#__assets') + ->where('name = ' . $db->quote('com_modules.module.' . (int) $pk)); + $db->setQuery($query); + $db->execute(); + + $query->clear() + ->delete('#__assets') + ->where('name = ' . $db->quote('com_advancedmodules.module.' . (int) $pk)); + $db->setQuery($query); + $db->execute(); + + // Trigger the after delete event. + $dispatcher->trigger($this->event_after_delete, [$context, $table]); + + // Clear module cache + parent::cleanCache($table->module, $table->client_id); + } + + // Clear modules cache + $this->cleanCache(); + + return true; + } + + /** + * Method to duplicate modules. + * + * @param array &$pks An array of primary key IDs. + * + * @return boolean|JException Boolean true on success, JException instance on error + * + * @throws Exception + */ + public function duplicate(&$pks) + { + $user = JFactory::getUser(); + + // Access checks. + if ( ! $user->authorise('core.create', 'com_modules')) + { + throw new Exception(JText::_('JERROR_CORE_CREATE_NOT_PERMITTED')); + } + + $db = $this->getDbo(); + $query = $db->getQuery(true); + $inserts = []; + $table = $this->getTable(); + $table_adv = JTable::getInstance('AdvancedModules', 'AdvancedModulesTable'); + + foreach ($pks as $pk) + { + if ($table->load($pk, true)) + { + // Reset the id to create a new record. + $table->id = 0; + + // Alter the title. + $m = null; + + if (RL_RegEx::match('\((\d+)\)$', $table->title, $m)) + { + $table->title = RL_RegEx::replace('\(\d+\)$', '(' . ($m[1] + 1) . ')', $table->title); + } + + $data = $this->generateNewTitle(0, $table->title, $table->position); + $table->title = $data[0]; + + // Unpublish duplicate module + $table->published = 0; + + if ( ! $table->check() || ! $table->store()) + { + throw new Exception($table->getError()); + } + + $query->clear() + ->select($db->quoteName('menuid')) + ->from($db->quoteName('#__modules_menu')) + ->where($db->quoteName('moduleid') . ' = ' . (int) $pk); + + $db->setQuery($query); + $rows = $db->loadColumn(); + + foreach ($rows as $menuid) + { + $inserts[(int) $table->id . '-' . (int) $menuid] = (int) $table->id . ',' . (int) $menuid; + } + + if ($table->id && ! $table_adv->load($table->id)) + { + $table_adv->moduleid = $table->id; + $db->insertObject($table_adv->getTableName(), $table_adv, $table_adv->getKeyName()); + } + + if ($table_adv->load($pk, true)) + { + $table_adv->moduleid = $table->id; + + $rules = JAccess::getAssetRules('com_modules.module.' . $pk); + $table_adv->setRules($rules); + + if ( ! $table_adv->check() || ! $table_adv->store()) + { + throw new Exception($table_adv->getError()); + } + } + } + else + { + throw new Exception($table->getError()); + } + } + + if ( ! empty($inserts)) + { + // Module-Menu Mapping: Do it in one query + $query->clear() + ->insert('#__modules_menu') + ->columns([$db->quoteName('moduleid'), $db->quoteName('menuid')]); + foreach ($inserts as $insert) + { + $query->values($insert); + } + $db->setQuery($query); + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + throw new Exception($e->getMessage(), 500); + } + } + + // Clear modules cache + $this->cleanCache(); + + return true; + } + + /** + * Method to set color of modules. + * + * @param array &$pks An array of primary key IDs. + * @param string $color RGB color + * + * @return boolean True if successful. + * @throws Exception + */ + public function setcolor(&$pks, $color) + { + // Set the variables + $db = $this->getDbo(); + $user = JFactory::getUser(); + $table_adv = JTable::getInstance('AdvancedModules', 'AdvancedModulesTable'); + + foreach ($pks as $pk) + { + if ( ! $user->authorise('core.edit', 'com_modules')) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); + + return false; + } + + if ( ! $table_adv->load($pk)) + { + $table_adv->moduleid = $pk; + $db->insertObject($table_adv->getTableName(), $table_adv, $table_adv->getKeyName()); + } + + if ( ! $table_adv->load($pk, true)) + { + continue; + } + + $params = json_decode($table_adv->params); + if (is_null($params)) + { + $params = (object) []; + } + + $params->color = strtolower($color); + + $table_adv->params = json_encode($params); + + if ( ! $table_adv->check() || ! $table_adv->store()) + { + $this->setError($table_adv->getError()); + + return false; + } + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + + /** + * Method to change the title. + * + * @param integer $category_id The id of the category. Not used here. + * @param string $title The title. + * @param string $position The position. + * + * @return array Contains the modified title. + */ + protected function generateNewTitle($category_id, $title, $position) + { + // Alter the title & alias + $table = $this->getTable(); + + while ($table->load(['position' => $position, 'title' => $title])) + { + $title = RL_String::increment($title); + } + + return [$title]; + } + + /** + * Method to get the client object + * + * @return void + */ + public function &getClient() + { + return $this->_client; + } + + /** + * Method to get the record form. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm A JForm object on success, false on failure + */ + public function getForm($data = [], $loadData = true) + { + // The folder and element vars are passed when saving the form. + if (empty($data)) + { + $item = $this->getItem(); + $clientId = $item->client_id; + $module = $item->module; + $id = $item->id; + } + else + { + $clientId = JArrayHelper::getValue($data, 'client_id'); + $module = JArrayHelper::getValue($data, 'module'); + $id = JArrayHelper::getValue($data, 'id'); + } + + // Add the default fields directory + $baseFolder = ($clientId) ? JPATH_ADMINISTRATOR : JPATH_SITE; + JForm::addFieldPath($baseFolder . '/modules' . '/' . $module . '/field'); + + // These variables are used to add data from the plugin XML files. + $this->setState('item.client_id', $clientId); + $this->setState('item.module', $module); + + // Get the form. + if ($clientId == 1) + { + $form = $this->loadForm('com_advancedmodules.module.admin', 'moduleadmin', ['control' => 'jform', 'load_data' => $loadData], true); + + // Display language field to filter admin custom menus per language + if ( ! JModuleHelper::isAdminMultilang()) + { + $form->setFieldAttribute('language', 'type', 'hidden'); + } + } + else + { + $form = $this->loadForm('com_advancedmodules.module', 'module', ['control' => 'jform', 'load_data' => $loadData], true); + } + + if (empty($form)) + { + return false; + } + + $form->setFieldAttribute('position', 'client', $this->getState('item.client_id') == 0 ? 'site' : 'administrator'); + + $user = JFactory::getUser(); + + /** + * Check for existing module + * Modify the form based on Edit State access controls. + */ + if ($id != 0 && ( ! $user->authorise('core.edit.state', 'com_modules.module.' . (int) $id)) + || ($id == 0 && ! $user->authorise('core.edit.state', 'com_modules')) + ) + { + // Disable fields for display. + $form->setFieldAttribute('ordering', 'disabled', 'true'); + $form->setFieldAttribute('published', 'disabled', 'true'); + $form->setFieldAttribute('publish_up', 'disabled', 'true'); + $form->setFieldAttribute('publish_down', 'disabled', 'true'); + + // Disable fields while saving. + // The controller has already verified this is a record you can edit. + $form->setFieldAttribute('ordering', 'filter', 'unset'); + $form->setFieldAttribute('published', 'filter', 'unset'); + $form->setFieldAttribute('publish_up', 'filter', 'unset'); + $form->setFieldAttribute('publish_down', 'filter', 'unset'); + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + */ + protected function loadFormData() + { + $app = JFactory::getApplication(); + + // Check the session for previously entered form data. + $data = $app->getUserState('com_advancedmodules.edit.module.data', []); + + if (empty($data)) + { + $data = $this->getItem(); + + // Pre-select some filters (Status, Module Position, Language, Access Level) in edit form if those have been selected in Module Manager + if ( ! $data->id) + { + $filters = (array) $app->getUserState('com_advancedmodules.modules.filter'); + $data->set('published', $app->input->getInt('published', ((isset($filters['state']) && $filters['state'] !== '') ? $filters['state'] : null))); + $data->set('position', $app->input->getInt('position', (! empty($filters['position']) ? $filters['position'] : null))); + $data->set('language', $app->input->getString('language', (! empty($filters['language']) ? $filters['language'] : null))); + $data->set('access', $app->input->getInt('access', (! empty($filters['access']) ? $filters['access'] : JFactory::getConfig()->get('access')))); + } + + // Avoid to delete params of a second module opened in a new browser tab while new one is not saved yet. + if (empty($data->params)) + { + // This allows us to inject parameter settings into a new module. + $params = $app->getUserState('com_advancedmodules.add.module.params'); + + if (is_array($params)) + { + $data->set('params', $params); + } + } + } + + if ( ! empty($data->mirror_id)) + { + $data->advancedparams['mirror_module'] = ($data->mirror_id < 0) ? 2 : 1; + $data->advancedparams['mirror_moduleid'] = ($data->mirror_id < 0) ? $data->mirror_id * -1 : $data->mirror_id; + } + + if (isset($data->category)) + { + $data->advancedparams['category'] = $data->category; + } + + $this->preprocessData('com_advancedmodules.module', $data); + + return $data; + } + + /** + * Method to get a single record. + * + * @param integer $pk The id of the primary key. + * + * @return mixed Object on success, false on failure. + */ + public function getItem($pk = null) + { + $pk = ( ! empty($pk)) ? (int) $pk : (int) $this->getState('module.id'); + $db = $this->getDbo(); + $query = $db->getQuery(true); + + if (isset($this->_cache[$pk])) + { + return $this->_cache[$pk]; + } + + // Get a row instance. + $table = $this->getTable(); + + // Attempt to load the row. + $return = $table->load($pk); + + // Check for a table object error. + if ($return === false && $error = $table->getError()) + { + $this->setError($error); + + return false; + } + + // Check if we are creating a new extension. + if (empty($pk)) + { + $extensionId = (int) $this->getState('extension.id'); + if ( ! $extensionId) + { + JFactory::getApplication()->redirect(JRoute::_('index.php?option=com_advancedmodules&view=modules', false)); + + return false; + } + + $query->clear() + ->select('e.element, e.client_id') + ->from('#__extensions AS e') + ->where('e.extension_id = ' . $extensionId) + ->where('e.type = ' . $db->quote('module')); + $db->setQuery($query); + + try + { + $extension = $db->loadObject(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + if (empty($extension)) + { + $this->setError('COM_MODULES_ERROR_CANNOT_FIND_MODULE'); + + return false; + } + + // Extension found, prime some module values. + $table->module = $extension->element; + $table->client_id = $extension->client_id; + } + + // Convert to the JObject before adding other data. + $properties = $table->getProperties(1); + $this->_cache[$pk] = JArrayHelper::toObject($properties, 'JObject'); + + // Convert the params field to an array. + $this->_cache[$pk]->params = json_decode($table->params, true); + if (is_null($this->_cache[$pk]->params)) + { + $this->_cache[$pk]->params = []; + } + + // Advanced parameters + // Get a row instance. + $table_adv = $this->getTable('AdvancedModules', 'AdvancedModulesTable'); + + // Attempt to load the row. + $table_adv->load($pk); + + $this->_cache[$pk]->asset_id = $table_adv->asset_id; + $this->_cache[$pk]->mirror_id = $table_adv->mirror_id; + $this->_cache[$pk]->category = $table_adv->category; + + // Convert the params field to an array. + $this->_cache[$pk]->advancedparams = json_decode($table_adv->params, true); + if (is_null($this->_cache[$pk]->params)) + { + $this->_cache[$pk]->advancedparams = []; + } + + $this->_cache[$pk]->advancedparams = $this->initAssignments($pk, $this->_cache[$pk]); + + $assigned = []; + $assignment = 0; + if (isset($this->_cache[$pk]->advancedparams['assignto_menuitems']) && isset($this->_cache[$pk]->advancedparams['assignto_menuitems_selection'])) + { + $assigned = $this->_cache[$pk]->advancedparams['assignto_menuitems_selection']; + if ($this->_cache[$pk]->advancedparams['assignto_menuitems'] == 1 && empty($this->_cache[$pk]->advancedparams['assignto_menuitems_selection'])) + { + $assignment = '-'; + } + else if ($this->_cache[$pk]->advancedparams['assignto_menuitems'] == 1) + { + $assignment = '1'; + } + else if ($this->_cache[$pk]->advancedparams['assignto_menuitems'] == 2) + { + $assignment = '-1'; + } + } + + $this->_cache[$pk]->assigned = $assigned; + $this->_cache[$pk]->assignment = $assignment; + + // Get the module XML. + $client = JApplicationHelper::getClientInfo($table->client_id); + $path = JPath::clean($client->path . '/modules/' . $table->module . '/' . $table->module . '.xml'); + + $this->_cache[$pk]->xml = null; + if (file_exists($path)) + { + $this->_cache[$pk]->xml = simplexml_load_file($path); + } + + return $this->_cache[$pk]; + } + + /** + * Get the necessary data to load an item help screen. + * + * @return object An object with key, url, and local properties for loading the item help screen. + */ + public function getHelp() + { + return (object) ['key' => $this->helpKey, 'url' => $this->helpURL]; + } + + /** + * Returns a reference to the a Table object, always creating it. + * + * @param string $type The table type to instantiate + * @param string $prefix A prefix for the table class name. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return JTable A database object + */ + public function getTable($type = 'Module', $prefix = 'JTable', $config = []) + { + return JTable::getInstance($type, $prefix, $config); + } + + /** + * Prepare and sanitise the table prior to saving. + * + * @param JTable $table The database object + * + * @return void + */ + protected function prepareTable($table) + { + $table->title = htmlspecialchars_decode($table->title, ENT_QUOTES); + $table->position = trim($table->position); + } + + /** + * Method to preprocess the form + * + * @param JForm $form A form object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * @throws Exception if there is an error loading the form. + */ + protected function preprocessForm(JForm $form, $data, $group = 'content') + { + jimport('joomla.filesystem.path'); + + $lang = JFactory::getLanguage(); + $clientId = $this->getState('item.client_id'); + $module = $this->getState('item.module'); + + $client = JApplicationHelper::getClientInfo($clientId); + $formFile = JPath::clean($client->path . '/modules/' . $module . '/' . $module . '.xml'); + + // Load the core and/or local language file(s). + $lang->load($module, $client->path, null, false, true) + || $lang->load($module, $client->path . '/modules/' . $module, null, false, true); + + if (file_exists($formFile)) + { + // Get the module form. + if ( ! $form->loadFile($formFile, false, '//config')) + { + throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); + } + + // Attempt to load the xml file. + if ( ! $xml = simplexml_load_file($formFile)) + { + throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); + } + + // Get the help data from the XML file if present. + $help = $xml->xpath('/extension/help'); + + if ( ! empty($help)) + { + $helpKey = trim((string) $help[0]['key']); + $helpURL = trim((string) $help[0]['url']); + + $this->helpKey = $helpKey ? $helpKey : $this->helpKey; + $this->helpURL = $helpURL ? $helpURL : $this->helpURL; + } + } + + // Load the default advanced params + JForm::addFormPath(JPATH_ADMINISTRATOR . '/components/com_advancedmodules/models/forms'); + $form->loadFile('advanced', false); + + // Trigger the default form events. + parent::preprocessForm($form, $data, $group); + } + + /** + * Loads ContentHelper for filters before validating data. + * + * @param object $form The form to validate against. + * @param array $data The data to validate. + * @param string $group The name of the group(defaults to null). + * + * @return mixed Array of filtered data if valid, false otherwise. + */ + public function validate($form, $data, $group = null) + { + require_once JPATH_ADMINISTRATOR . '/components/com_content/helpers/content.php'; + + return parent::validate($form, $data, $group); + } + + /** + * Applies the text filters to arbitrary text as per settings for current user groups + * + * @param text $text The string to filter + * + * @return string The filtered string + */ + public static function filterText($text) + { + return JComponentHelper::filterText($text); + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + */ + public function save($data) + { + $advancedparams = JFactory::getApplication()->input->get('advancedparams', [], 'array'); + + $dispatcher = JEventDispatcher::getInstance(); + $input = JFactory::getApplication()->input; + $table = $this->getTable(); + $pk = ( ! empty($data['id'])) ? $data['id'] : (int) $this->getState('module.id'); + $isNew = true; + $context = $this->option . '.' . $this->name; + + // Include the plugins for the save event. + JPluginHelper::importPlugin($this->events_map['save']); + + // Load the row if saving an existing record. + if ($pk > 0) + { + $table->load($pk); + $isNew = false; + } + + // Alter the title and published state for Save as Copy + if ($input->get('task') == 'save2copy') + { + $orig_table = clone $this->getTable(); + $orig_table->load((int) $input->getInt('id')); + $data['published'] = 0; + + if ($data['title'] == $orig_table->title) + { + $data['title'] = RL_String::increment($data['title']); + } + } + + // correct the publish date details + if (isset($advancedparams['assignto_date_publish_up'])) + { + RL_Date::applyTimezone($advancedparams['assignto_date_publish_up']); + } + + if (isset($advancedparams['assignto_date_publish_down'])) + { + RL_Date::applyTimezone($advancedparams['assignto_date_publish_down']); + } + + if (isset($advancedparams['assignto_date'])) + { + $publish_up = 0; + $publish_down = 0; + if ($advancedparams['assignto_date'] == 2) + { + $publish_up = $advancedparams['assignto_date_publish_down']; + } + else if ($advancedparams['assignto_date'] == 1) + { + $publish_up = $advancedparams['assignto_date_publish_up']; + $publish_down = $advancedparams['assignto_date_publish_down']; + } + + $data['publish_up'] = $publish_up; + $data['publish_down'] = $publish_down; + } + + $lang = '*'; + if (isset($advancedparams['assignto_languages']) + && $advancedparams['assignto_languages'] == 1 + && count($advancedparams['assignto_languages_selection']) === 1 + ) + { + $lang = (string) $advancedparams['assignto_languages_selection'][0]; + } + $data['language'] = $lang; + + // Bind the data. + if ( ! $table->bind($data)) + { + $this->setError($table->getError()); + + return false; + } + + // Prepare the row for saving + $this->prepareTable($table); + + // Check the data. + if ( ! $table->check()) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the before save event. + $result = $dispatcher->trigger($this->event_before_save, [$context, &$table, $isNew]); + + if (in_array(false, $result, true)) + { + $this->setError($table->getError()); + + return false; + } + + // Store the data. + if ( ! $table->store()) + { + $this->setError($table->getError()); + + return false; + } + + $table_adv = JTable::getInstance('AdvancedModules', 'AdvancedModulesTable'); + + $table_adv->moduleid = $table->id; + if ($table_adv->moduleid && ! $table_adv->load($table_adv->moduleid)) + { + $db = $table_adv->getDbo(); + $db->insertObject($table_adv->getTableName(), $table_adv, $table_adv->getKeyName()); + } + + if (isset($data['rules'])) + { + $table_adv->_title = $data['title']; + $table_adv->setRules($data['rules']); + } + + $table_adv->mirror_id = 0; + + if ( ! empty($advancedparams['mirror_module'])) + { + $table_adv->mirror_id = $advancedparams['mirror_module'] == 2 ? $advancedparams['mirror_moduleid'] * -1 : $advancedparams['mirror_moduleid']; + unset($advancedparams['mirror_module']); + unset($advancedparams['mirror_moduleid']); + } + + unset($advancedparams['category_select']); + + if (isset($advancedparams['category'])) + { + $table_adv->category = $advancedparams['category']; + unset($advancedparams['category']); + } + + $table_adv->params = json_encode($advancedparams); + + // Check the row + $table_adv->check(); + + // Store the row + if ( ! $table_adv->store()) + { + $this->setError($table_adv->getError()); + } + + // + // Process the menu link mappings. + // + if ( ! $this->saveMenuAssignments($table->id, $advancedparams)) + { + return false; + } + + $db = $this->getDbo(); + + // Remove unused assets entry (uses core com_modules rules) + $query = $db->getQuery(true) + ->delete('#__assets') + ->where('name = ' . $db->quote('com_advancedmodules.module.' . (int) $table->id)); + $db->setQuery($query); + $db->execute(); + + // Trigger the after save event. + $dispatcher->trigger($this->event_after_save, [$context, &$table, $isNew]); + + // Compute the extension id of this module in case the controller wants it. + $query = $db->getQuery(true) + ->select('extension_id') + ->from('#__extensions AS e') + ->join('LEFT', '#__modules AS m ON e.element = m.module') + ->where('m.id = ' . (int) $table->id); + $db->setQuery($query); + + try + { + $extensionId = $db->loadResult(); + } + catch (RuntimeException $e) + { + throw new Exception($e->getMessage(), 500); + } + + $this->setState('module.extension_id', $extensionId); + $this->setState('module.id', $table->id); + + // Clear modules cache + $this->cleanCache(); + + // Clean module cache + parent::cleanCache($table->module, $table->client_id); + + return true; + } + + public function saveMenuAssignments($id, $advancedparams) + { + $assignment = isset($advancedparams['assignto_menuitems']) ? $advancedparams['assignto_menuitems'] : 0; + $items = isset($advancedparams['assignto_menuitems_selection']) ? $advancedparams['assignto_menuitems_selection'] : []; + + $empty = empty($items); + + switch ($assignment) + { + case 2: + $assignment = $empty ? 'all' : 'inverted'; + break; + + case 1: + $assignment = $empty ? 'none' : 'selection'; + break; + + case 0: + default: + $assignment = 'all'; + break; + } + + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->delete($db->quoteName('#__modules_menu')) + ->where($db->quoteName('moduleid') . ' = ' . (int) $id); + $db->setQuery($query); + $db->execute(); + + if ($assignment == 'none') + { + return true; + } + + // Check needed to stop a module being assigned to `All` + // and other menu items resulting in a module being displayed twice. + if ($assignment === 'all') + { + // Assign new module to `all` menu item associations. + $query->clear() + ->insert($db->quoteName('#__modules_menu')) + ->columns([$db->quoteName('moduleid'), $db->quoteName('menuid')]) + ->values((int) $id . ', 0'); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + return true; + } + + // Get the sign of the number. + $sign = $assignment == 'inverted' ? -1 : 1; + + // Preprocess the assigned array. + if ( ! is_array($items)) + { + $items = explode(',', $items); + } + $items = array_unique($items); + + $inserts = []; + foreach ($items as &$item) + { + if ( ! is_numeric($item)) + { + continue; + } + + $menuid = (int) $item * $sign; + + $inserts[] = (int) $id . ',' . $menuid; + } + + if (empty($inserts)) + { + return true; + } + + $query->clear() + ->insert($db->quoteName('#__modules_menu')) + ->columns([$db->quoteName('moduleid'), $db->quoteName('menuid')]); + + foreach ($inserts as $insert) + { + $query->values($insert); + } + + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + return true; + } + + /** + * Method to save the advanced parameters. + * + * @param array $data The form data. + * + * @return boolean True on success. + * @since 1.6 + */ + public function saveAdvancedParams($data, $id = 0) + { + if ( ! $id) + { + $id = JFactory::getApplication()->input->getInt('id'); + } + + if ( ! $id) + { + return true; + } + + require_once JPATH_ADMINISTRATOR . '/components/com_advancedmodules/tables/advancedmodules.php'; + $table_adv = JTable::getInstance('AdvancedModules', 'AdvancedModulesTable'); + $table_adv->moduleid = $id; + + if ($id && ! $table_adv->load($id)) + { + $db = $table_adv->getDbo(); + $db->insertObject($table_adv->getTableName(), $table_adv, $table_adv->getKeyName()); + } + + if (isset($data['rules'])) + { + $table_adv->_title = $data['title']; + $table_adv->setRules($data['rules']); + } + + $table_adv->params = json_encode($data); + + // Check the row + $table_adv->check(); + + try + { + // Store the data. + $table_adv->store(); + } + catch (RuntimeException $e) + { + throw new Exception($e->getMessage(), 500); + } + + return true; + } + + /** + * Method to get and save the module core menu assignments + * + * @param int $id The module id. + * + * @return boolean True on success. + * @since 1.6 + */ + public function initAssignments($id, &$module) + { + if ( ! $id) + { + $id = JFactory::getApplication()->input->getInt('id'); + } + + if (empty($id)) + { + $module->advancedparams = [ + 'assignto_menuitems' => $this->config->default_menu_assignment, + 'assignto_menuitems_selection' => [], + ]; + + AdvancedModulesModelModule::saveAdvancedParams($module->advancedparams, $id); + + return $module->advancedparams; + } + + if (is_object($module->advancedparams)) + { + $module->advancedparams = (array) $module->advancedparams; + } + + $changed = false; + + if ( ! isset($module->advancedparams['assignto_menuitems'])) + { + $this->setMenuItemAssignments($id, $module->advancedparams); + + $changed = true; + } + else if (isset($module->advancedparams['assignto_menuitems_selection'][0]) && strpos($module->advancedparams['assignto_menuitems_selection'][0], ',') !== false) + { + $module->advancedparams['assignto_menuitems_selection'] = explode(',', $module->advancedparams['assignto_menuitems_selection'][0]); + + $changed = true; + } + + if ( ! isset($module->advancedparams['assignto_date'])) + { + if ((isset($module->publish_up) && (int) $module->publish_up) + || (isset($module->publish_down) && (int) $module->publish_down) + ) + { + $module->advancedparams['assignto_date'] = 1; + $module->advancedparams['assignto_date_publish_up'] = isset($module->publish_up) ? $module->publish_up : ''; + $module->advancedparams['assignto_date_publish_down'] = isset($module->publish_down) ? $module->publish_down : ''; + + $changed = true; + } + } + + // Correct possible negative publish dates + if (isset($module->advancedparams['assignto_date_publish_up']) && (int) $module->advancedparams['assignto_date_publish_up'] < 0) + { + $module->advancedparams['assignto_date_publish_up'] = ''; + $changed = true; + } + + if (isset($module->advancedparams['assignto_date_publish_down']) && (int) $module->advancedparams['assignto_date_publish_down'] < 0) + { + $module->advancedparams['assignto_date_publish_down'] = ''; + $changed = true; + } + + if ( ! isset($module->advancedparams['assignto_languages'])) + { + if (isset($module->language) && $module->language && $module->language != '*') + { + $module->advancedparams['assignto_languages'] = 1; + $module->advancedparams['assignto_languages_selection'] = [$module->language]; + + $changed = true; + } + } + + if ($changed) + { + AdvancedModulesModelModule::saveAdvancedParams($module->advancedparams, $id); + } + + return $module->advancedparams; + } + + protected function setMenuItemAssignments($id, &$params) + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('m.menuid') + ->from('#__modules_menu AS m') + ->where('m.moduleid = ' . (int) $id); + $db->setQuery($query); + + $params['assignto_menuitems_selection'] = $db->loadColumn(); + $params['assignto_menuitems'] = 0; + + if (empty($params['assignto_menuitems_selection'])) + { + $params['assignto_menuitems_selection'] = []; + + return; + } + + if ($params['assignto_menuitems_selection'][0] == 0) + { + $params['assignto_menuitems_selection'] = []; + + return; + } + + if ($params['assignto_menuitems_selection'][0] < 0) + { + $params['assignto_menuitems'] = 2; + } + else + { + $params['assignto_menuitems'] = 1; + } + + foreach ($params['assignto_menuitems_selection'] as $i => $menuitem) + { + if ($menuitem < 0) + { + $params['assignto_menuitems_selection'][$i] = $menuitem * -1; + } + } + } + + /** + * A protected method to get a set of ordering conditions. + * + * @param object $table A record object. + * + * @return array An array of conditions to add to add to ordering queries. + */ + protected function getReorderConditions($table) + { + $condition = []; + $condition[] = 'client_id = ' . (int) $table->client_id; + $condition[] = 'position = ' . $this->_db->quote($table->position); + + return $condition; + } + + /** + * Custom clean cache method for different clients + * + * @param string $group The name of the plugin group to import (defaults to null). + * @param integer $client_id The client ID. [optional] + * + * @return void + */ + protected function cleanCache($group = null, $client_id = 0) + { + parent::cleanCache('com_advancedmodules', $this->getClient()); + } + + /** + * Method to test whether a record can be deleted. + * + * @param object $record A record object. + * + * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. + */ + protected function canDelete($record) + { + if ( ! empty($record->id)) + { + if ($record->state != -2) + { + return; + } + $user = JFactory::getUser(); + + return $user->authorise('core.delete', 'com_modules.module.' . (int) $record->id); + } + } + + /** + * Method override to check if you can edit an existing record. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + */ + protected function allowEdit($data = [], $key = 'id') + { + // Initialise variables. + $recordId = (int) isset($data[$key]) ? $data[$key] : 0; + $user = JFactory::getUser(); + $userId = $user->get('id'); + + // Check general edit permission first. + if ($user->authorise('core.edit', 'com_modules.module.' . $recordId)) + { + return true; + } + + // Since there is no asset tracking, revert to the component permissions. + return parent::allowEdit($data, $key); + } + + /** + * Function that gets the config settings + * + * @return Object + */ + private function getConfig() + { + if (isset($this->config)) + { + return $this->config; + } + + $this->config = RL_Parameters::getInstance()->getComponentParams('advancedmodules'); + + return $this->config; + } +} diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/models/modules.php b/deployed/regularlabs/administrator/components/com_advancedmodules/models/modules.php new file mode 100644 index 00000000..b1861bf4 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/models/modules.php @@ -0,0 +1,646 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use RegularLabs\Library\Parameters as RL_Parameters; + +/** + * Modules Component Module Model + */ +class AdvancedModulesModelModules extends JModelList +{ + /** + * Constructor. + * + * @param array $config An optional associative array of configuration settings. + * + * @see JController + * @since 1.6 + */ + public function __construct($config = []) + { + if (empty($config['filter_fields'])) + { + $config['filter_fields'] = [ + 'id', 'a.id', + 'color', 'a.color', + 'category', 'aa.category', + 'title', 'a.title', + 'checked_out', 'a.checked_out', + 'checked_out_time', 'a.checked_out_time', + 'published', 'a.published', 'state', + 'access', 'a.access', + 'ag.title', 'access_level', + 'ordering', 'a.ordering', + 'module', 'a.module', + 'a.language', + 'l.title', 'language_title', + 'publish_up', 'a.publish_up', + 'publish_down', 'a.publish_down', + 'client_id', 'a.client_id', + 'position', 'a.position', + 'menuitem', + 'menuid', + 'name', 'e.name', + ]; + } + + parent::__construct($config); + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. + * @param string $direction An optional direction (asc|desc). + * + * @return void + */ + protected function populateState($ordering = null, $direction = null) + { + $app = JFactory::getApplication('administrator'); + + // Load the filter state. + $search = trim($this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search')); + $this->setState('filter.search', $search); + + $access = $this->getUserStateFromRequest($this->context . '.filter.access', 'filter_access'); + $this->setState('filter.access', $access); + + $state = $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'string'); + $this->setState('filter.state', $state); + + $position = $this->getUserStateFromRequest($this->context . '.filter.position', 'filter_position', '', 'string'); + $this->setState('filter.position', $position); + + $module = $this->getUserStateFromRequest($this->context . '.filter.module', 'filter_module', '', 'string'); + $this->setState('filter.module', $module); + + $category = $this->getUserStateFromRequest($this->context . '.filter.category', 'filter_category', '', 'string'); + $this->setState('filter.category', $category); + + // Special handling for filter client_id. + + // Try to get current Client selection from $_POST. + $clientId = $app->input->getString('client_id', null); + + // Client Site(0) or Administrator(1) selected? + if (in_array($clientId, ['0', '1'])) + { + // Not the same client like saved previous one? + if ($clientId != $app->getUserState($this->context . '.client_id')) + { + // Save current selection as new previous value in session. + $app->setUserState($this->context . '.client_id', $clientId); + + // Reset pagination. + $app->input->set('limitstart', 0); + } + } + + // No Client selected? + else + { + // Try to get previous one from session. + $clientId = (string) $app->getUserState($this->context . '.client_id'); + + // Client not Site(0) and not Administrator(1)? So, set to Site(0). + if ( ! in_array($clientId, ['0', '1'])) + { + $clientId = '0'; + } + } + + // Modal view should return only front end modules + if (JFactory::getApplication()->input->get('layout') == 'modal') + { + $clientId = 0; + } + + $this->setState('filter.client_id', $clientId); + + $language = $this->getUserStateFromRequest($this->context . '.filter.language', 'filter_language', ''); + $this->setState('filter.language', $language); + + // Load the parameters. + $params = JComponentHelper::getParams('com_advancedmodules'); + $this->setState('params', $params); + + // List state information. + $this->getConfig(); + list($default_ordering, $default_direction) = explode(' ', $this->config->default_ordering, 2); + + $this->setState('list.fullordering', $this->config->default_ordering); + parent::populateState($default_ordering, $default_direction); + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState($this->context, new stdClass); + + // Pre-fill the list options + if ( ! property_exists($data, 'list')) + { + $this->getConfig(); + list($default_ordering, $default_direction) = explode(' ', $this->config->default_ordering, 2); + + $data->list = [ + 'direction' => $default_direction, + 'limit' => $this->state->{'list.limit'}, + 'ordering' => $default_ordering, + 'fullordering' => $this->config->default_ordering, + 'start' => $this->state->{'list.start'}, + ]; + } + + return $data; + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . trim($this->getState('filter.search')); + $id .= ':' . $this->getState('filter.access'); + $id .= ':' . $this->getState('filter.state'); + $id .= ':' . $this->getState('filter.position'); + $id .= ':' . $this->getState('filter.module'); + $id .= ':' . $this->getState('filter.category'); + $id .= ':' . $this->getState('filter.menuid'); + $id .= ':' . $this->getState('filter.client_id'); + $id .= ':' . $this->getState('filter.language'); + + return parent::getStoreId($id); + } + + /** + * Returns an object list + * + * @param string $query The query + * @param int $limitstart Offset + * @param int $limit The number of records + * + * @return array + */ + protected function _getList($query, $limitstart = 0, $limit = 0) + { + $ordering = strtolower($this->getState('list.ordering', 'ordering')); + $orderDirn = strtoupper($this->getState('list.direction', 'ASC')); + + if (in_array($ordering, ['menuid', 'name'])) + { + $this->_db->setQuery($query); + $result = $this->_db->loadObjectList(); + $this->translate($result); + JArrayHelper::sortObjects($result, $ordering, $orderDirn == 'DESC' ? -1 : 1, true, true); + $total = count($result); + $this->cache[$this->getStoreId('getTotal')] = $total; + + if ($total < $limitstart) + { + $limitstart = 0; + $this->setState('list.start', 0); + } + + return array_slice($result, $limitstart, $limit ? $limit : null); + } + + if ($ordering != 'color') + { + if ($ordering == 'ordering') + { + $query->order('a.position ASC'); + $ordering = 'a.ordering'; + } + + if ($ordering == 'language_title') + { + $ordering = 'l.manifest_cache'; + } + + $query->order($this->_db->quoteName($ordering) . ' ' . $orderDirn); + + if ($ordering == 'position') + { + $query->order('a.ordering ASC'); + } + + $result = parent::_getList($query, $limitstart, $limit); + $this->translate($result); + + return $result; + } + + $this->_db->setQuery($query); + $result = $this->_db->loadObjectList(); + $this->translate($result); + $newresult = []; + + foreach ($result as $i => $row) + { + $params = json_decode($row->advancedparams); + if (is_null($params)) + { + $params = (object) []; + } + + $color = isset($params->color) ? str_replace('#', '', $params->color) : 'none'; + $color = empty($color) ? 'none' : $color; + $newresult['_' . $color . '_' . (($i + 1) / 10000)] = $row; + } + + if ($orderDirn == 'DESC') + { + krsort($newresult); + } + else + { + ksort($newresult); + } + + $newresult = array_values($newresult); + $total = count($newresult); + $this->cache[$this->getStoreId('getTotal')] = $total; + + if ($total < $limitstart) + { + $limitstart = 0; + $this->setState('list.start', 0); + } + + return array_slice($newresult, $limitstart, $limit ? $limit : null); + } + + /** + * Translate a list of objects + * + * @param array &$items The array of objects + * + * @return array The array of translated objects + */ + protected function translate(&$items) + { + $lang = JFactory::getLanguage(); + $client = $this->getState('filter.client_id') ? 'administrator' : 'site'; + + foreach ($items as $item) + { + $extension = $item->module; + $source = constant('JPATH_' . strtoupper($client)) . "/modules/$extension"; + $lang->load("$extension.sys", constant('JPATH_' . strtoupper($client)), null, false, true) + || $lang->load("$extension.sys", $source, null, false, true); + $item->name = JText::_($item->name); + + if ($item->mirror_id > 0) + { + $item->menuid = JText::sprintf( + 'AMM_MIRRORING_MODULE', + '[' + . $item->mirror_id . ']' + ); + continue; + } + + if ($item->mirror_id < 0) + { + $item->menuid = JText::sprintf( + 'AMM_MIRRORING_MODULE_OPPOSITE', + '[' + . ($item->mirror_id * -1) . ']' + ); + continue; + } + + if (is_null($item->menuid)) + { + $item->menuid = JText::_('JNONE'); + continue; + } + + if ($item->menuid < 0) + { + $item->menuid = JText::_('COM_MODULES_ASSIGNED_VARIES_EXCEPT'); + continue; + } + + if ($item->menuid > 0) + { + $item->menuid = JText::_('COM_MODULES_ASSIGNED_VARIES_ONLY'); + continue; + } + + $item->menuid = JText::_('JALL'); + } + } + + /** + * Build an SQL query to load the list data. + * + * @return JDatabaseQuery + */ + protected function getListQuery() + { + $db = $this->getDbo(); + + $query = $db->getQuery(true) + // Select the required fields from the table. + ->select('a.id') + ->from($db->quoteName('#__modules', 'a')) + // Join over the module menus + ->join('LEFT', $db->quoteName('#__modules_menu', 'mm') . ' ON ' . $db->quoteName('mm.moduleid') . ' = ' . $db->quoteName('a.id')) + // Join over the extensions + ->join('LEFT', $db->quoteName('#__extensions', 'e') . ' ON ' . $db->quoteName('e.element') . ' = ' . $db->quoteName('a.module')) + // Join advanced params + ->join('LEFT', $db->quoteName('#__advancedmodules', 'aa') . ' ON ' . $db->quoteName('aa.moduleid') . ' = ' . $db->quoteName('a.id')); + + // Filter by module + $module = $this->getState('filter.module'); + if ($module) + { + $query->where($db->quoteName('a.module') . ' = ' . $db->quote($module)); + } + + // Filter by category + $category = $this->getState('filter.category'); + if ($category) + { + $query->where($db->quoteName('aa.category') . ' = ' . $db->quote($category)); + } + + $wheres = []; + + // Filter by menuid + $menuid = $this->getState('filter.menuid'); + + switch ($menuid) + { + case '': + break; + case '0': + $wheres[] = $db->quoteName('mm.menuid') . ' = 0'; + break; + case '-': + $wheres[] = $db->quoteName('mm.menuid') . ' IS NULL'; + break; + case '-1': + $wheres[] = $db->quoteName('mm.menuid') . ' LIKE \'-%\''; + break; + case '-2': + $wheres[] = $db->quoteName('mm.menuid') . ' NOT LIKE \'-%\' AND ' . $db->quoteName('mm.menuid') . ' != 0'; + break; + default: + $wheres[] = '(' . $db->quoteName('mm.menuid') . ' IN (0, ' . (int) $menuid . ')' + . ' OR (' . $db->quoteName('mm.menuid') . ' LIKE \'-%\' AND ' . $db->quoteName('mm.menuid') . ' != ' . $db->quote('-' . (int) $menuid) . '))'; + break; + } + + // Filter by position + if ($position = $this->getState('filter.position')) + { + $wheres[] = $db->quoteName('a.position') . ' = ' . $db->quote($position != 'none' ? $position : ''); + } + + // Filter by current user access level. + $user = JFactory::getUser(); + + // Get the current user for authorisation checks + if ($user->authorise('core.admin') !== true) + { + $groups = implode(',', $user->getAuthorisedViewLevels()); + $wheres[] = 'a.access IN (' . $groups . ')'; + } + + // Filter by access level. + if ($access = $this->getState('filter.access')) + { + $wheres[] = 'a.access = ' . (int) $access; + } + + // Filter on the language. + if ($language = $this->getState('filter.language')) + { + $wheres[] = $db->quoteName('a.language') . ' = ' . $db->quote($language); + } + + // Filter by published state + $published = $this->getState('filter.state'); + + // Modal view should return only front end modules + if (JFactory::getApplication()->input->get('layout') == 'modal') + { + $published = 1; + } + + if (is_numeric($published)) + { + $wheres[] = $db->quoteName('a.published') . ' = ' . (int) $published; + } + elseif ($published == '') + { + $wheres[] = '(' . $db->quoteName('a.published') . ' IN (0, 1))'; + } + + // Filter by client. + $clientId = $this->getState('filter.client_id'); + + // Modal view should return only front end modules + if (JFactory::getApplication()->input->get('layout') == 'modal') + { + $clientId = 0; + } + + if (is_numeric($clientId)) + { + $wheres[] = $db->quoteName('a.client_id') . ' = ' . (int) $clientId + . ' AND ' . $db->quoteName('e.client_id') . ' =' . (int) $clientId; + } + + // Modal view should return only specific language and ALL + if (JFactory::getApplication()->input->get('layout') == 'modal') + { + if (JFactory::getApplication()->isClient('site') && JLanguageMultilang::isEnabled()) + { + $query->where($db->quoteName('a.language') . ' in (' . $db->quote(JFactory::getLanguage()->getTag()) . ',' . $db->quote('*') . ')'); + } + } + elseif ($language = $this->getState('filter.language')) + { + // Filter on the language. + $query->where($db->quoteName('a.language') . ' = ' . $db->quote($language)); + } + + // Set wheres + foreach ($wheres as $where) + { + $query->where($where); + } + + // Filter by search in title + $search = trim($this->getState('filter.search')); + + if ( ! empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where($db->quoteName('a.id') . ' = ' . (int) substr($search, 3)); + } + else + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('(' + . $db->quoteName('a.title') . ' LIKE ' . $search + . ' OR ' . $db->quoteName('a.note') . ' LIKE ' . $search + . ')'); + } + } + + $db->setQuery($query); + $ids = $db->loadColumn(); + + foreach ($ids as $key => $id) + { + if (JFactory::getUser()->authorise('core.edit', 'com_modules.module.' . $id)) + { + continue; + } + + unset($ids[$key]); + } + + if ( ! empty($ids)) + { + $mirror_wheres = $wheres; + array_unshift( + $mirror_wheres, + $db->quoteName('aa.mirror_id') . ' IN (' . implode(',', $ids) . ',-' . implode(',-', $ids) . ')' + ); + + $query->clear('where'); + + // Set wheres + foreach ($mirror_wheres as $where) + { + $query->where($where); + } + + $db->setQuery($query); + $mirror_ids = $db->loadColumn(); + + $mirror_ids = array_unique($mirror_ids); + + foreach ($mirror_ids as $key => $id) + { + if (JFactory::getUser()->authorise('core.edit', 'com_modules.module.' . $id)) + { + continue; + } + + unset($mirror_ids[$key]); + } + + $ids = array_merge($ids, $mirror_ids); + } + + $query = $db->getQuery(true) + // Select the required fields from the table. + ->select( + $this->getState( + 'list.select', + 'a.id, a.title, a.note, a.position, a.module, a.language,' . + 'a.checked_out, a.checked_out_time, a.published as published, e.enabled as enabled, a.access, a.ordering, a.publish_up, a.publish_down' + ) + ) + ->from('#__modules AS a') + // Join over the language + ->select($db->quoteName('l.title', 'language_title')) + ->select($db->quoteName('l.image', 'language_image')) + ->join('LEFT', $db->quoteName('#__languages', 'l') . ' ON ' . $db->quoteName('l.lang_code') . ' = ' . $db->quoteName('a.language')) + ->select($db->quoteName('le.element', 'language')) + ->join('LEFT', $db->quoteName('#__extensions', 'le') . ' ON ' . $db->quoteName('le.element') . ' = ' . $db->quoteName('a.language')) + // Join over the users for the checked out user. + ->select($db->quoteName('uc.name', 'editor')) + ->join('LEFT', $db->quoteName('#__users', 'uc') . ' ON ' . $db->quoteName('uc.id') . ' = ' . $db->quoteName('a.checked_out')) + // Join over the asset groups. + ->select($db->quoteName('ag.title', 'access_level')) + ->join('LEFT', $db->quoteName('#__viewlevels', 'ag') . ' ON ' . $db->quoteName('ag.id') . ' = ' . $db->quoteName('a.access')) + // Join over the module menus + ->select('MIN(mm.menuid) AS menuid') + ->join('LEFT', $db->quoteName('#__modules_menu', 'mm') . ' ON ' . $db->quoteName('mm.moduleid') . ' = ' . $db->quoteName('a.id')) + // Join over the extensions + ->select($db->quoteName('e.name', 'name')) + ->join('LEFT', $db->quoteName('#__extensions', 'e') . ' ON ' . $db->quoteName('e.element') . ' = ' . $db->quoteName('a.module')) + // Join over the advanced params + ->select($db->quoteName('aa.params', 'advancedparams')) + ->select($db->quoteName('aa.mirror_id', 'mirror_id')) + ->select($db->quoteName('aa.category', 'category')) + ->join('LEFT', $db->quoteName('#__advancedmodules', 'aa') . ' ON ' . $db->quoteName('aa.moduleid') . ' = ' . $db->quoteName('a.id')) + // Group + ->group( + 'a.id, a.title, a.note, a.position, a.module, a.language, a.checked_out,' . + 'a.checked_out_time, a.published, a.access, a.ordering, uc.name, ag.title, e.name,' . + 'uc.id, ag.id, mm.moduleid, e.element, a.publish_up, a.publish_down, e.enabled' + ); + + if (empty($ids)) + { + $query->where('1 = 0'); + + return $query; + } + + $ids = array_unique($ids); + + $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')'); + + return $query; + } + + /** + * Function that gets the config settings + * + * @return Object + */ + protected function getConfig() + { + if (isset($this->config)) + { + return $this->config; + } + + $this->config = RL_Parameters::getInstance()->getComponentParams('advancedmodules'); + + return $this->config; + } +} diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/models/positions.php b/deployed/regularlabs/administrator/components/com_advancedmodules/models/positions.php new file mode 100644 index 00000000..d88304c2 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/models/positions.php @@ -0,0 +1,240 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * Modules Component Positions Model + */ +class AdvancedModulesModelPositions extends JModelList +{ + /** + * Constructor. + * + * @param array $config An optional associative array of configuration settings. + * + * @see JController + * @since 1.6 + */ + public function __construct($config = []) + { + if (empty($config['filter_fields'])) + { + $config['filter_fields'] = [ + 'value', + 'templates', + ]; + } + + parent::__construct($config); + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. + * @param string $direction An optional direction (asc|desc). + * + * @return void + */ + protected function populateState($ordering = 'value', $direction = 'asc') + { + $app = JFactory::getApplication('administrator'); + + // Load the filter state. + $search = trim($this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search')); + $this->setState('filter.search', $search); + + $published = $this->getUserStateFromRequest($this->context . '.filter.published', 'filter_published', '', 'string'); + $this->setState('filter.published', $published); + + $clientId = $app->input->getInt('client_id', 0); + $this->setState('filter.client_id', $clientId); + + $template = $this->getUserStateFromRequest($this->context . '.filter.template', 'filter_template', '', 'string'); + $this->setState('filter.template', $template); + + $type = $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', '', 'string'); + $this->setState('filter.type', $type); + + // Load the parameters. + $params = JComponentHelper::getParams('com_advancedmodules'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to get an array of data items. + * + * @return mixed An array of data items on success, false on failure. + */ + public function getItems() + { + if ( ! isset($this->items)) + { + $lang = JFactory::getLanguage(); + $search = trim($this->getState('filter.search')); + $state = $this->getState('filter.state'); + $clientId = $this->getState('filter.client_id'); + $filter_template = $this->getState('filter.template'); + $type = $this->getState('filter.type'); + $ordering = $this->getState('list.ordering'); + $direction = $this->getState('list.direction'); + $limitstart = $this->getState('list.start'); + $limit = $this->getState('list.limit'); + $client = JApplicationHelper::getClientInfo($clientId); + + if ($type != 'template') + { + // Get the database object and a new query object. + $query = $this->_db->getQuery(true) + ->select('DISTINCT(m.position) as value') + ->from('#__modules as m') + ->where('m.client_id = ' . (int) $clientId); + if ($search) + { + $search = $this->_db->quote('%' . str_replace(' ', '%', $this->_db->escape(trim($search), true) . '%')); + $query->where('m.position LIKE ' . $search); + } + + $this->_db->setQuery($query); + + try + { + $positions = $this->_db->loadObjectList('value'); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + foreach ($positions as $value => $position) + { + $positions[$value] = []; + } + } + else + { + $positions = []; + } + + // Load the positions from the installed templates. + foreach (ModulesHelper::getTemplates($clientId) as $template) + { + $path = JPath::clean($client->path . '/templates/' . $template->element . '/templateDetails.xml'); + + if (file_exists($path)) + { + $xml = simplexml_load_file($path); + + if (isset($xml->positions[0])) + { + $lang->load('tpl_' . $template->element . '.sys', $client->path, null, false, true) + || $lang->load('tpl_' . $template->element . '.sys', $client->path . '/templates/' . $template->element, null, false, true); + + foreach ($xml->positions[0] as $position) + { + $value = (string) $position['value']; + $label = (string) $position; + + if ( ! $value) + { + $value = $label; + $label = preg_replace('/[^a-zA-Z0-9_\-]/', '_', 'TPL_' . $template->element . '_POSITION_' . $value); + $altlabel = preg_replace('/[^a-zA-Z0-9_\-]/', '_', 'COM_MODULES_POSITION_' . $value); + + if ( ! $lang->hasKey($label) && $lang->hasKey($altlabel)) + { + $label = $altlabel; + } + } + + if ($type == 'user' || ($state != '' && $state != $template->enabled)) + { + unset($positions[$value]); + } + elseif (preg_match(chr(1) . $search . chr(1) . 'i', $value) && ($filter_template == '' || $filter_template == $template->element)) + { + if ( ! isset($positions[$value])) + { + $positions[$value] = []; + } + + $positions[$value][$template->name] = $label; + } + } + } + } + } + + $this->total = count($positions); + + if ($limitstart >= $this->total) + { + $limitstart = $limitstart < $limit ? 0 : $limitstart - $limit; + $this->setState('list.start', $limitstart); + } + + if ($ordering == 'value') + { + if ($direction == 'asc') + { + ksort($positions); + } + else + { + krsort($positions); + } + } + else + { + if ($direction == 'asc') + { + asort($positions); + } + else + { + arsort($positions); + } + } + + $this->items = array_slice($positions, $limitstart, $limit ? $limit : null); + } + + return $this->items; + } + + /** + * Method to get the total number of items. + * + * @return int The total number of items. + */ + public function getTotal() + { + if ( ! isset($this->total)) + { + $this->getItems(); + } + + return $this->total; + } +} diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/models/select.php b/deployed/regularlabs/administrator/components/com_advancedmodules/models/select.php new file mode 100644 index 00000000..158412bc --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/models/select.php @@ -0,0 +1,153 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * Module model. + */ +class AdvancedModulesModelSelect extends JModelList +{ + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. + * @param string $direction An optional direction (asc|desc). + * + * @return void + */ + protected function populateState($ordering = null, $direction = null) + { + $app = JFactory::getApplication('administrator'); + + // Load the filter state. + $clientId = $app->getUserState('com_advancedmodules.modules.client_id', 0); + $this->setState('filter.client_id', (int) $clientId); + + // Load the parameters. + $params = JComponentHelper::getParams('com_advancedmodules'); + $this->setState('params', $params); + + // Manually set limits to get all modules. + $this->setState('list.limit', 0); + $this->setState('list.start', 0); + $this->setState('list.ordering', 'a.name'); + $this->setState('list.direction', 'ASC'); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.client_id'); + + return parent::getStoreId($id); + } + + /** + * Build an SQL query to load the list data. + * + * @return JDatabaseQuery + */ + protected function getListQuery() + { + $db = $this->getDbo(); + $clientId = $this->getState('filter.client_id'); + + $query = $db->getQuery(true) + // Select the required fields from the table. + ->select( + $this->getState( + 'list.select', + 'a.extension_id, a.name, a.element AS module' + ) + ) + ->from('#__extensions AS a') + // Filter by module + ->where('a.type = ' . $db->quote('module')) + // Filter by client. + ->where('a.client_id = ' . (int) $clientId) + // Filter by enabled + ->where('a.enabled = 1') + // Add the list ordering clause. + ->order($db->escape($this->getState('list.ordering', 'a.ordering')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + /** + * Method to get a list of items. + * + * @return mixed An array of objects on success, false on failure. + */ + public function getItems() + { + // Get the list of items from the database. + $items = parent::getItems(); + + $client = JApplicationHelper::getClientInfo($this->getState('filter.client_id', 0)); + $lang = JFactory::getLanguage(); + + // Loop through the results to add the XML metadata, + // and load language support. + foreach ($items as &$item) + { + $path = JPath::clean($client->path . '/modules/' . $item->module . '/' . $item->module . '.xml'); + + if (file_exists($path)) + { + $item->xml = simplexml_load_file($path); + } + else + { + $item->xml = null; + } + + // 1.5 Format; Core files or language packs then + // 1.6 3PD Extension Support + $lang->load($item->module . '.sys', $client->path, null, false, true) + || $lang->load($item->module . '.sys', $client->path . '/modules/' . $item->module, null, false, true); + $item->name = JText::_($item->name); + + if (isset($item->xml) && $text = trim($item->xml->description)) + { + $item->desc = JText::_($text); + } + else + { + $item->desc = JText::_('COM_MODULES_NODESCRIPTION'); + } + } + + $items = JArrayHelper::sortObjects($items, 'name', 1, true, true); + + // TODO: Use the cached XML from the extensions table? + + return $items; + } +} diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/script.install.helper.php b/deployed/regularlabs/administrator/components/com_advancedmodules/script.install.helper.php new file mode 100644 index 00000000..baf8e1ed --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/script.install.helper.php @@ -0,0 +1,852 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +class Com_AdvancedModulesInstallerScriptHelper +{ + public $name = ''; + public $alias = ''; + public $extname = ''; + public $extension_type = ''; + public $plugin_folder = 'system'; + public $module_position = 'status'; + public $client_id = 1; + public $install_type = 'install'; + public $show_message = true; + public $db = null; + public $softbreak = null; + + public function __construct(&$params) + { + $this->extname = $this->extname ?: $this->alias; + $this->db = JFactory::getDbo(); + } + + public function preflight($route, JAdapterInstance $adapter) + { + if ( ! in_array($route, ['install', 'update'])) + { + return true; + } + + JFactory::getLanguage()->load('plg_system_regularlabsinstaller', JPATH_PLUGINS . '/system/regularlabsinstaller'); + + if ($this->show_message && $this->isInstalled()) + { + $this->install_type = 'update'; + } + + if ($this->onBeforeInstall($route) === false) + { + return false; + } + + return true; + } + + public function postflight($route, JAdapterInstance $adapter) + { + $this->removeGlobalLanguageFiles(); + $this->removeUnusedLanguageFiles(); + + JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); + + if ( ! in_array($route, ['install', 'update'])) + { + return true; + } + + $this->fixExtensionNames(); + $this->updateUpdateSites(); + $this->removeAdminCache(); + + if ($this->onAfterInstall($route) === false) + { + return false; + } + + if ($route == 'install') + { + $this->publishExtension(); + } + + if ($this->show_message) + { + $this->addInstalledMessage(); + } + + JFactory::getCache()->clean('com_plugins'); + JFactory::getCache()->clean('_system'); + + return true; + } + + public function isInstalled() + { + if ( ! is_file($this->getInstalledXMLFile())) + { + return false; + } + + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('extension_id')) + ->from('#__extensions') + ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); + $this->db->setQuery($query, 0, 1); + $result = $this->db->loadResult(); + + return empty($result) ? false : true; + } + + public function getMainFolder() + { + switch ($this->extension_type) + { + case 'plugin' : + return JPATH_PLUGINS . '/' . $this->plugin_folder . '/' . $this->extname; + + case 'component' : + return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; + + case 'module' : + return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; + + case 'library' : + return JPATH_SITE . '/libraries/' . $this->extname; + } + } + + public function getInstalledXMLFile() + { + return $this->getXMLFile($this->getMainFolder()); + } + + public function getCurrentXMLFile() + { + return $this->getXMLFile(__DIR__); + } + + public function getXMLFile($folder) + { + switch ($this->extension_type) + { + case 'module' : + return $folder . '/mod_' . $this->extname . '.xml'; + + default : + return $folder . '/' . $this->extname . '.xml'; + } + } + + public function uninstallExtension($extname, $type = 'plugin', $folder = 'system', $show_message = true) + { + if (empty($extname)) + { + return; + } + + $folders = []; + + switch ($type) + { + case 'plugin'; + $folders[] = JPATH_PLUGINS . '/' . $folder . '/' . $extname; + break; + + case 'component': + $folders[] = JPATH_ADMINISTRATOR . '/components/com_' . $extname; + $folders[] = JPATH_SITE . '/components/com_' . $extname; + break; + + case 'module': + $folders[] = JPATH_ADMINISTRATOR . '/modules/mod_' . $extname; + $folders[] = JPATH_SITE . '/modules/mod_' . $extname; + break; + } + + if ( ! $this->foldersExist($folders)) + { + return; + } + + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('extension_id')) + ->from('#__extensions') + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName($type, $extname))) + ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($type)); + + if ($type == 'plugin') + { + $query->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($folder)); + } + + $this->db->setQuery($query); + $ids = $this->db->loadColumn(); + + if (empty($ids)) + { + foreach ($folders as $folder) + { + JFolder::delete($folder); + } + + return; + } + + $ignore_ids = JFactory::getApplication()->getUserState('rl_ignore_uninstall_ids', []); + + if (JFactory::getApplication()->input->get('option') == 'com_installer' && JFactory::getApplication()->input->get('task') == 'remove') + { + // Don't attempt to uninstall extensions that are already selected to get uninstalled by them selves + $ignore_ids = array_merge($ignore_ids, JFactory::getApplication()->input->get('cid', [], 'array')); + JFactory::getApplication()->input->set('cid', array_merge($ignore_ids, $ids)); + } + + $ids = array_diff($ids, $ignore_ids); + + if (empty($ids)) + { + return; + } + + $ignore_ids = array_merge($ignore_ids, $ids); + JFactory::getApplication()->setUserState('rl_ignore_uninstall_ids', $ignore_ids); + + foreach ($ids as $id) + { + $tmpInstaller = new JInstaller; + $tmpInstaller->uninstall($type, $id); + } + + if ($show_message) + { + JFactory::getApplication()->enqueueMessage( + JText::sprintf( + 'COM_INSTALLER_UNINSTALL_SUCCESS', + JText::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($type)) + ) + ); + } + } + + public function foldersExist($folders = []) + { + foreach ($folders as $folder) + { + if (is_dir($folder)) + { + return true; + } + } + + return false; + } + + public function uninstallPlugin($extname, $folder = 'system', $show_message = true) + { + $this->uninstallExtension($extname, 'plugin', $folder, $show_message); + } + + public function uninstallComponent($extname, $show_message = true) + { + $this->uninstallExtension($extname, 'component', null, $show_message); + } + + public function uninstallModule($extname, $show_message = true) + { + $this->uninstallExtension($extname, 'module', null, $show_message); + } + + public function publishExtension() + { + switch ($this->extension_type) + { + case 'plugin' : + $this->publishPlugin(); + + case 'module' : + $this->publishModule(); + } + } + + public function publishPlugin() + { + $query = $this->db->getQuery(true) + ->update('#__extensions') + ->set($this->db->quoteName('enabled') . ' = 1') + ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) + ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); + $this->db->setQuery($query); + $this->db->execute(); + } + + public function publishModule() + { + // Get module id + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('id')) + ->from('#__modules') + ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) + ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + if ( ! $id) + { + return; + } + + // check if module is already in the modules_menu table (meaning is is already saved) + $query->clear() + ->select($this->db->quoteName('moduleid')) + ->from('#__modules_menu') + ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); + $this->db->setQuery($query, 0, 1); + $exists = $this->db->loadResult(); + + if ($exists) + { + return; + } + + // Get highest ordering number in position + $query->clear() + ->select($this->db->quoteName('ordering')) + ->from('#__modules') + ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) + ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) + ->order('ordering DESC'); + $this->db->setQuery($query, 0, 1); + $ordering = $this->db->loadResult(); + $ordering++; + + // publish module and set ordering number + $query->clear() + ->update('#__modules') + ->set($this->db->quoteName('published') . ' = 1') + ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) + ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) + ->where($this->db->quoteName('id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + + // add module to the modules_menu table + $query->clear() + ->insert('#__modules_menu') + ->columns([$this->db->quoteName('moduleid'), $this->db->quoteName('menuid')]) + ->values((int) $id . ', 0'); + $this->db->setQuery($query); + $this->db->execute(); + } + + public function addInstalledMessage() + { + JFactory::getApplication()->enqueueMessage( + JText::sprintf( + JText::_($this->install_type == 'update' ? 'RLI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'RLI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), + '' . JText::_($this->name) . '', + '' . $this->getVersion() . '', + $this->getFullType() + ) + ); + } + + public function getPrefix() + { + switch ($this->extension_type) + { + case 'plugin'; + return JText::_('plg_' . strtolower($this->plugin_folder)); + + case 'component': + return JText::_('com'); + + case 'module': + return JText::_('mod'); + + case 'library': + return JText::_('lib'); + + default: + return $this->extension_type; + } + } + + public function getElementName($type = null, $extname = null) + { + $type = is_null($type) ? $this->extension_type : $type; + $extname = is_null($extname) ? $this->extname : $extname; + + switch ($type) + { + case 'component' : + return 'com_' . $extname; + + case 'module' : + return 'mod_' . $extname; + + case 'plugin' : + default: + return $extname; + } + } + + public function getFullType() + { + return JText::_('RLI_' . strtoupper($this->getPrefix())); + } + + public function getVersion($file = '') + { + $file = $file ?: $this->getCurrentXMLFile(); + + if ( ! is_file($file)) + { + return ''; + } + + $xml = JApplicationHelper::parseXMLInstallFile($file); + + if ( ! $xml || ! isset($xml['version'])) + { + return ''; + } + + return $xml['version']; + } + + public function isNewer() + { + if ( ! $installed_version = $this->getVersion($this->getInstalledXMLFile())) + { + return true; + } + + $package_version = $this->getVersion(); + + return version_compare($installed_version, $package_version, '<='); + } + + public function canInstall() + { + // The extension is not installed yet + if ( ! $installed_version = $this->getVersion($this->getInstalledXMLFile())) + { + return true; + } + + // The free version is installed. So any version is ok to install + if (strpos($installed_version, 'PRO') === false) + { + return true; + } + + // Current package is a pro version, so all good + if (strpos($this->getVersion(), 'PRO') !== false) + { + return true; + } + + JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); + + JFactory::getApplication()->enqueueMessage(JText::_('RLI_ERROR_PRO_TO_FREE'), 'error'); + + JFactory::getApplication()->enqueueMessage( + html_entity_decode( + JText::sprintf( + 'RLI_ERROR_UNINSTALL_FIRST', + '', + '', + JText::_($this->name) + ) + ), 'error' + ); + + return false; + } + + /* + * Fixes incorrectly formed versions because of issues in old packager + */ + public function fixFileVersions($file) + { + if (is_array($file)) + { + foreach ($file as $f) + { + self::fixFileVersions($f); + } + + return; + } + + if ( ! is_string($file) || ! is_file($file)) + { + return; + } + + $contents = file_get_contents($file); + + if ( + strpos($contents, 'FREEFREE') === false + && strpos($contents, 'FREEPRO') === false + && strpos($contents, 'PROFREE') === false + && strpos($contents, 'PROPRO') === false + ) + { + return; + } + + $contents = str_replace( + ['FREEFREE', 'FREEPRO', 'PROFREE', 'PROPRO'], + ['FREE', 'PRO', 'FREE', 'PRO'], + $contents + ); + + JFile::write($file, $contents); + } + + public function onBeforeInstall($route) + { + if ( ! $this->canInstall()) + { + return false; + } + + return true; + } + + public function onAfterInstall($route) + { + } + + public function delete($files = []) + { + foreach ($files as $file) + { + if (is_dir($file)) + { + JFolder::delete($file); + } + + if (is_file($file)) + { + JFile::delete($file); + } + } + } + + public function fixAssetsRules($rules = '{"core.admin":[],"core.manage":[]}') + { + // replace default rules value {} with the correct initial value + $query = $this->db->getQuery(true) + ->update($this->db->quoteName('#__assets')) + ->set($this->db->quoteName('rules') . ' = ' . $this->db->quote($rules)) + ->where($this->db->quoteName('title') . ' = ' . $this->db->quote('com_' . $this->extname)) + ->where($this->db->quoteName('rules') . ' = ' . $this->db->quote('{}')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function fixExtensionNames() + { + switch ($this->extension_type) + { + case 'module' : + $this->fixModuleNames(); + } + } + + private function fixModuleNames() + { + // Get module id + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('id')) + ->from('#__modules') + ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) + ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); + $this->db->setQuery($query, 0, 1); + $module_id = $this->db->loadResult(); + + if (empty($module_id)) + { + return; + } + + $title = 'Regular Labs - ' . JText::_($this->name); + + $query->clear() + ->update('#__modules') + ->set($this->db->quoteName('title') . ' = ' . $this->db->quote($title)) + ->where($this->db->quoteName('id') . ' = ' . (int) $module_id) + ->where($this->db->quoteName('title') . ' LIKE ' . $this->db->quote('NoNumber%')); + $this->db->setQuery($query); + $this->db->execute(); + + // Fix module assets + + // Get asset id + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('id')) + ->from('#__assets') + ->where($this->db->quoteName('name') . ' = ' . $this->db->quote('com_modules.module.' . (int) $module_id)) + ->where($this->db->quoteName('title') . ' LIKE ' . $this->db->quote('NoNumber%')); + $this->db->setQuery($query, 0, 1); + $asset_id = $this->db->loadResult(); + + if (empty($asset_id)) + { + return; + } + + $query->clear() + ->update('#__assets') + ->set($this->db->quoteName('title') . ' = ' . $this->db->quote($title)) + ->where($this->db->quoteName('id') . ' = ' . (int) $asset_id); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function updateUpdateSites() + { + $this->removeOldUpdateSites(); + $this->updateNamesInUpdateSites(); + $this->updateHttptoHttpsInUpdateSites(); + $this->removeDuplicateUpdateSite(); + $this->updateDownloadKey(); + } + + private function removeOldUpdateSites() + { + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('nonumber.nl%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + if ( ! $id) + { + return; + } + + $query->clear() + ->delete('#__update_sites') + ->where($this->db->quoteName('update_site_id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + + $query->clear() + ->delete('#__update_sites_extensions') + ->where($this->db->quoteName('update_site_id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function updateNamesInUpdateSites() + { + $name = JText::_($this->name); + if ($this->alias != 'extensionmanager') + { + $name = 'Regular Labs - ' . $name; + } + + $query = $this->db->getQuery(true) + ->update('#__update_sites') + ->set($this->db->quoteName('name') . ' = ' . $this->db->quote($name)) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function updateHttptoHttpsInUpdateSites() + { + $query = $this->db->getQuery(true) + ->update('#__update_sites') + ->set($this->db->quoteName('location') . ' = REPLACE(' + . $this->db->quoteName('location') . ', ' + . $this->db->quote('http://') . ', ' + . $this->db->quote('https://') + . ')') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('http://download.regularlabs.com%')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function removeDuplicateUpdateSite() + { + // First check to see if there is a pro entry + + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')) + ->where($this->db->quoteName('location') . ' NOT LIKE ' . $this->db->quote('%pro=1%')); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + // Otherwise just get the first match + if ( ! $id) + { + $query->clear() + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + // Remove pro=1 from the found update site + $query->clear() + ->update('#__update_sites') + ->set($this->db->quoteName('location') + . ' = replace(' . $this->db->quoteName('location') . ', ' . $this->db->quote('&pro=1') . ', ' . $this->db->quote('') . ')') + ->where($this->db->quoteName('update_site_id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + } + + if ( ! $id) + { + return; + } + + $query->clear() + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')) + ->where($this->db->quoteName('update_site_id') . ' != ' . $id); + $this->db->setQuery($query); + $ids = $this->db->loadColumn(); + + if (empty($ids)) + { + return; + } + + $query->clear() + ->delete('#__update_sites') + ->where($this->db->quoteName('update_site_id') . ' IN (' . implode(',', $ids) . ')'); + $this->db->setQuery($query); + $this->db->execute(); + + $query->clear() + ->delete('#__update_sites_extensions') + ->where($this->db->quoteName('update_site_id') . ' IN (' . implode(',', $ids) . ')'); + $this->db->setQuery($query); + $this->db->execute(); + } + + // Save the download key from the Regular Labs Extension Manager config to the update sites + private function updateDownloadKey() + { + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('params')) + ->from('#__extensions') + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote('com_regularlabsmanager')); + $this->db->setQuery($query); + $params = $this->db->loadResult(); + + if ( ! $params) + { + return; + } + + $params = json_decode($params); + + if ( ! isset($params->key)) + { + return; + } + + // Add the key on all regularlabs.com urls + $query->clear() + ->update('#__update_sites') + ->set($this->db->quoteName('extra_query') . ' = ' . $this->db->quote('k=' . $params->key)) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function removeAdminCache() + { + $this->delete([JPATH_ADMINISTRATOR . '/cache/regularlabs']); + $this->delete([JPATH_ADMINISTRATOR . '/cache/nonumber']); + } + + private function removeGlobalLanguageFiles() + { + if ($this->extension_type == 'library') + { + return; + } + + $language_files = JFolder::files(JPATH_ADMINISTRATOR . '/language', '\.' . $this->getPrefix() . '_' . $this->extname . '\.', true, true); + + // Remove override files + foreach ($language_files as $i => $language_file) + { + if (strpos($language_file, '/overrides/') === false) + { + continue; + } + + unset($language_files[$i]); + } + + if (empty($language_files)) + { + return; + } + + JFile::delete($language_files); + } + + private function removeUnusedLanguageFiles() + { + if ($this->extension_type == 'library') + { + return; + } + + $installed_languages = array_merge( + JFolder::folders(JPATH_SITE . '/language'), + JFolder::folders(JPATH_ADMINISTRATOR . '/language') + ); + + $languages = array_diff( + JFolder::folders(__DIR__ . '/language'), + $installed_languages + ); + + $delete_languages = []; + + foreach ($languages as $language) + { + $delete_languages[] = $this->getMainFolder() . '/language/' . $language; + } + + if (empty($delete_languages)) + { + return; + } + + // Remove folders + $this->delete($delete_languages); + } +} diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/script.install.php b/deployed/regularlabs/administrator/components/com_advancedmodules/script.install.php new file mode 100644 index 00000000..cbeb387a --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/script.install.php @@ -0,0 +1,353 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +require_once __DIR__ . '/script.install.helper.php'; + +class Com_AdvancedModulesInstallerScript extends Com_AdvancedModulesInstallerScriptHelper +{ + public $name = 'ADVANCED_MODULE_MANAGER'; + public $alias = 'advancedmodulemanager'; + public $extname = 'advancedmodules'; + public $extension_type = 'component'; + + public function uninstall($adapter) + { + $this->uninstallPlugin($this->extname, $folder = 'system'); + } + + public function onBeforeInstall($route) + { + // Fix incorrectly formed versions because of issues in old packager + $this->fixFileVersions( + [ + JPATH_ADMINISTRATOR . '/components/com_advancedmodules/advancedmodules.xml', + JPATH_PLUGINS . '/system/advancedmodules/advancedmodules.xml', + ] + ); + } + + public function onAfterInstall($route) + { + $this->createTable(); + $this->fixAssignments(); + $this->fixAssetIdField(); + $this->fixMirrorIdField(); + $this->fixCategoryField(); + $this->removeAdminMenu(); + $this->removeFrontendComponentFromDB(); + $this->deleteOldFiles(); + $this->fixAssetsRules(); + } + + private function createTable() + { + // main table + $query = "CREATE TABLE IF NOT EXISTS `#__advancedmodules` ( + `moduleid` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `asset_id` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `mirror_id` INT(10) NOT NULL DEFAULT '0', + `category` VARCHAR(50) NOT NULL, + `params` TEXT NOT NULL, + PRIMARY KEY (`moduleid`) + ) DEFAULT CHARSET=utf8;"; + $this->db->setQuery($query); + $this->db->execute(); + } + + private function fixAssetIdField() + { + // add asset_id column + $query = "SHOW COLUMNS FROM `" . $this->db->getPrefix() . "advancedmodules` LIKE 'asset_id'"; + $this->db->setQuery($query); + $has_field = $this->db->loadResult(); + if ($has_field) + { + return; + } + + $query = "ALTER TABLE `#__advancedmodules` ADD `asset_id` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `moduleid`"; + $this->db->setQuery($query); + $this->db->execute(); + } + + private function fixMirrorIdField() + { + // add mirror_id column + $query = "SHOW COLUMNS FROM `" . $this->db->getPrefix() . "advancedmodules` LIKE 'mirror_id'"; + $this->db->setQuery($query); + $has_field = $this->db->loadResult(); + + if ($has_field) + { + return; + } + + $query = "ALTER TABLE `#__advancedmodules` ADD `mirror_id` INT(10) NOT NULL DEFAULT '0' AFTER `asset_id`"; + $this->db->setQuery($query); + $this->db->execute(); + + $this->fixMirrorIdFieldFixParams(); + } + + private function fixCategoryField() + { + // add asset_id column + $query = "SHOW COLUMNS FROM `" . $this->db->getPrefix() . "advancedmodules` LIKE 'category'"; + $this->db->setQuery($query); + $has_field = $this->db->loadResult(); + if ($has_field) + { + return; + } + + $query = "ALTER TABLE `#__advancedmodules` ADD COLUMN `category` VARCHAR(50) NOT NULL AFTER `mirror_id`"; + $this->db->setQuery($query); + $this->db->execute(); + } + + private function fixMirrorIdFieldFixParams() + { + // correct old keys and values + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('moduleid', 'id')) + ->select($this->db->quoteName('params')) + ->from($this->db->quoteName('#__advancedmodules')); + $this->db->setQuery($query); + $rows = $this->db->loadObjectList(); + + foreach ($rows as $row) + { + if (empty($row->params)) + { + continue; + } + + $params = json_decode($row->params); + + if (is_null($params)) + { + continue; + } + + // set urls_regex value if assignto_urls is used + if (empty($params->mirror_module) || empty($params->mirror_moduleid)) + { + continue; + } + + $mirror_id = $params->mirror_moduleid; + unset($params->mirror_module); + unset($params->mirror_moduleid); + + $query->clear() + ->update($this->db->quoteName('#__advancedmodules')) + ->set($this->db->quoteName('mirror_id') . ' = ' . (int) $mirror_id) + ->set($this->db->quoteName('params') . ' = ' . $this->db->quote(json_encode($params))) + ->where($this->db->quoteName('moduleid') . ' = ' . (int) $row->id); + $this->db->setQuery($query); + $this->db->execute(); + } + } + + private function removeAdminMenu() + { + // hide admin menu + $query = $this->db->getQuery(true) + ->delete($this->db->quoteName('#__menu')) + ->where($this->db->quoteName('path') . ' = ' . $this->db->quote('advancedmodules')) + ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('component')) + ->where($this->db->quoteName('client_id') . ' = 1'); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function removeFrontendComponentFromDB() + { + // remove frontend component from extensions table + $query = $this->db->getQuery(true) + ->delete($this->db->quoteName('#__extensions')) + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote('com_advancedmodules')) + ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('component')) + ->where($this->db->quoteName('client_id') . ' = 0'); + $this->db->setQuery($query); + $this->db->execute(); + + JFactory::getCache()->clean('_system'); + } + + private function fixAssignments() + { + $this->fixAssignmentsRemoveInitialAssignments(); + $this->fixAssignmentsCorrectOldKeys(); + } + + private function fixAssignmentsRemoveInitialAssignments() + { + // remove initial menu assignment settings + $query = $this->db->getQuery(true) + ->update($this->db->quoteName('#__advancedmodules')) + ->set($this->db->quoteName('params') . ' = ' . $this->db->quote('')) + ->where($this->db->quoteName('params') . ' = ' . $this->db->quote('{"assignto_menuitems":0,"assignto_menuitems_selection":[]}')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function fixAssignmentsCorrectOldKeys() + { + // correct old keys and values + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('moduleid', 'id')) + ->select($this->db->quoteName('params')) + ->from($this->db->quoteName('#__advancedmodules')); + $this->db->setQuery($query); + $rows = $this->db->loadObjectList(); + + foreach ($rows as $row) + { + if (empty($row->params)) + { + continue; + } + + if ($row->params[0] != '{') + { + $row->params = str_replace('assignto_secscats', 'assignto_cats', $row->params); + $row->params = str_replace('flexicontent', 'fc', $row->params); + + $params = JRegistryFormat::getInstance('INI')->stringToObject($row->params); + } + else + { + $params = json_decode($row->params); + if (is_null($params)) + { + $params = (object) []; + } + } + + // move tooltip to notes field + if ( ! empty($params->tooltip)) + { + $query->clear() + ->update($this->db->quoteName('#__modules')) + ->set($this->db->quoteName('note') . ' = ' . $this->db->quote($params->tooltip)) + ->where($this->db->quoteName('id') . ' = ' . (int) $row->id); + $this->db->setQuery($query); + $this->db->execute(); + unset($params->tooltip); + } + + // concatenate sef and non-sef url fields + if (isset($params->assignto_urls_selection_sef)) + { + $params->assignto_urls_selection = trim($params->assignto_urls_selection . "\n" . $params->assignto_urls_selection_sef); + unset($params->assignto_urls_selection_sef); + unset($params->show_url_field); + } + + // set urls_regex value if assignto_urls is used + if ( ! empty($params->assignto_urls) && ! isset($params->assignto_urls_regex)) + { + $params->assignto_urls_regex = 1; + } + + foreach ($params as $k => &$v) + { + switch ($k) + { + case 'assignto_php_selection': + case 'assignto_urls_selection': + case 'assignto_ips_selection': + $v = str_replace(['\n', '\|'], ["\n", '|'], $v); + break; + case 'color': + $v = str_replace('#', '', $v); + $v = (empty($v) || $v == 'none') ? 'none' : $v; + if ($v && $v != 'none') + { + $v = '#' . strtolower($v); + } + break; + case 'assignto_users_selection': + if ( ! is_array($v)) + { + $v = explode('|', $v); + } + break; + default: + if ( + (substr($k, -10) == '_selection' || substr($k, -4) == '_inc') + && ! is_array($v) + ) + { + // convert | separated strings to arrays + $v = explode('|', $v); + } + break; + } + } + + if ( ! empty($params->assignto_cats_selection)) + { + foreach ($params->assignto_cats_selection as $key => $val) + { + if (strpos($val, ':') !== false) + { + $params->assignto_cats_selection[$key] = substr($val, strpos($val, ':') + 1); + } + } + } + + $params = json_encode($params); + + if ($params == $row->params) + { + continue; + } + + $query->clear() + ->update($this->db->quoteName('#__advancedmodules')) + ->set($this->db->quoteName('params') . ' = ' . $this->db->quote($params)) + ->where($this->db->quoteName('moduleid') . ' = ' . (int) $row->id); + $this->db->setQuery($query); + $this->db->execute(); + } + } + + private function deleteOldFiles() + { + JFile::delete( + [ + JPATH_ADMINISTRATOR . '/components/com_advancedmodules/script.advancedmodules.php', + JPATH_SITE . '/components/com_advancedmodules/advancedmodules.xml', + JPATH_SITE . '/components/com_advancedmodules/script.advancedmodules.php', + JPATH_SITE . '/plugins/system/advancedmodules/modulehelper.php', + ] + ); + } + + public function fixAssetsRules($rules = '') + { + $rules = '{"core.admin":[],"core.manage":[],"core.create":[],"core.delete":[],"core.edit":[],"core.edit.state":[]}'; + + parent::fixAssetsRules($rules); + + // Remove unused assets entry (uses com_modules) + $query = $this->db->getQuery(true) + ->delete('#__assets') + ->where('name LIKE ' . $this->db->quote('com_advancedmodules.module.%')); + $this->db->setQuery($query); + $this->db->execute(); + } + +} diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/tables/advancedmodules.php b/deployed/regularlabs/administrator/components/com_advancedmodules/tables/advancedmodules.php new file mode 100644 index 00000000..01fd0af9 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/tables/advancedmodules.php @@ -0,0 +1,82 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +class AdvancedModulesTable extends JTable +{ + public function __construct(&$db) + { + parent::__construct('#__advancedmodules', 'moduleid', $db); + } + + protected function _getAssetName() + { + $k = $this->_tbl_key; + + return 'com_modules.module.' . (int) $this->{$k}; + } + + protected function _getAssetTitle() + { + if (isset($this->_title)) + { + return $this->_title; + } + + $k = (int) $this->_tbl_key; + + if (empty($this->{$k})) + { + return parent::_getAssetTitle(); + } + + $db = $this->getDbo(); + + $query = $db->getQuery(true) + ->select('title') + ->from('#__modules') + ->where('id = ' . (int) $this->{$k}); + $db->setQuery($query); + + return $db->loadResult(); + } + + /** + * Method to get the parent asset id for the record + * + * @param JTable $table A JTable object for the asset parent + * @param integer $id + * + * @return integer + */ + protected function _getAssetParentId(JTable $table = null, $id = null) + { + $db = $this->getDbo(); + + $query = $db->getQuery(true) + ->select('id') + ->from('#__assets') + ->where('name = ' . $db->quote('com_modules')); + $db->setQuery($query); + + if ($assetId = $db->loadResult()) + { + return $assetId; + } + + return parent::_getAssetParentId($table, $id); + } +} + +class AdvancedModulesTableAdvancedModules extends AdvancedModulesTable +{ +} diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/views/module/tmpl/edit.php b/deployed/regularlabs/administrator/components/com_advancedmodules/views/module/tmpl/edit.php new file mode 100644 index 00000000..cef3b32e --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/views/module/tmpl/edit.php @@ -0,0 +1,277 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use RegularLabs\Library\Document as RL_Document; + +JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + +JHtml::_('jquery.framework'); +JHtml::_('behavior.formvalidator'); +JHtml::_('behavior.combobox'); +JHtml::_('formbehavior.chosen', '#jform_position', null, ['disable_search_threshold' => 0]); +JHtml::_('formbehavior.chosen', '.multipleCategories', null, ['placeholder_text_multiple' => JText::_('JOPTION_SELECT_CATEGORY')]); +JHtml::_('formbehavior.chosen', '.multipleTags', null, ['placeholder_text_multiple' => JText::_('JOPTION_SELECT_TAG')]); +JHtml::_('formbehavior.chosen', 'select'); + +$hasContent = empty($this->item->module) || isset($this->item->xml->customContent); +$hasContentFieldName = 'content'; + +// For a later improvement +if ($hasContent) +{ + $hasContentFieldName = 'content'; +} + +// Get Params Fieldsets +$this->fieldsets = $this->form->getFieldsets('params'); +$this->hidden_fields = ''; + +$script = " +Joomla.submitbutton = function(task) +{ + if (task == 'module.cancel' || document.formvalidator.isValid(document.getElementById('module-form'))) {"; +if ($hasContent) +{ + $script .= $this->form->getField($hasContentFieldName)->save(); +} +$script .= " + Joomla.submitform(task, document.getElementById('module-form')); + + jQuery('#permissions-sliders select').attr('disabled', 'disabled'); + + if (self != top) + { + window.top.setTimeout('window.parent.SqueezeBox.close();', 1000); + } + } + };"; +if (JFactory::getUser()->authorise('core.admin')) +{ + $script .= " + jQuery(document).ready(function() + { + // add alert on remove assignment buttons + jQuery('button.rl_remove_assignment').click(function() + { + if(confirm('" . str_replace('
', '\n', JText::_('AMM_DISABLE_ASSIGNMENT', true)) . "')) { + jQuery('div#toolbar-options button').click(); + } + }); + });"; +} + +RL_Document::scriptDeclaration($script); +RL_Document::script('regularlabs/script.min.js'); +RL_Document::script('regularlabs/toggler.min.js'); +?> + +
+ + + +
+ 'general']); ?> + + + +
+
+ item->xml) : ?> + item->xml->description) : ?> +

+ item->xml) + { + echo ($text = (string) $this->item->xml->name) ? JText::_($text) : $this->item->module; + } + else + { + echo JText::_('COM_MODULES_ERR_XML'); + } + ?> +

+
+ + item->client_id == 0 ? JText::_('JSITE') : JText::_('JADMINISTRATOR'); ?> + +
+
+ item->xml->description); + $this->fieldset = 'description'; + $long_description = JLayoutHelper::render('joomla.edit.fieldset', $this); + if ( ! $long_description) + { + $truncated = JHtmlString::truncate($short_description, 550, true, false); + if (strlen($truncated) > 500) + { + $long_description = $short_description; + $short_description = JHtmlString::truncate($truncated, 250); + if ($short_description == $long_description) + { + $long_description = ''; + } + } + } + ?> +

+ +

+ + + +

+ +
+ + +
+ + form->getInput($hasContentFieldName); + } + $this->fieldset = 'basic'; + $html = JLayoutHelper::render('joomla.edit.fieldset', $this); + echo $html ? '
' . $html : ''; + ?> +
+
+
+ form->renderField('showtitle'); ?> +
+
+ form->getLabel('position'); ?> +
+
+ loadTemplate('positions'); ?> +
+
+
+ fields = [ + 'published', + 'access', + 'ordering', + 'note', + ]; + ?> + + item->client_id == 0) : ?> +
+ config->show_category) : ?> + render($this->assignments, 'category'); ?> + + config->show_color) : ?> +
+
+ +
+
+ item->advancedparams['color']) && $this->item->advancedparams['color']) + ? str_replace('##', '#', $this->item->advancedparams['color']) + : 'none'; + + $element = new SimpleXMLElement( + '' + ); + $element->value = $color; + + $colorfield->setup($element, $color); + + echo $colorfield->__get('input'); + ?> +
+
+ + render($this->assignments, 'pre_post_html'); ?> + config->show_hideempty) : ?> + render($this->assignments, 'hideempty'); ?> + +
+ +
+
+ + + + + + + + + item->client_id == 0) : ?> + + loadTemplate('assignment'); ?> + + + + config->show_notes) : ?> + +
+ render($this->assignments, 'notes'); ?> +
+ + + + canDo->get('core.admin')) : ?> + + form->getInput('rules'); ?> + + + + fieldsets = []; + $this->ignore_fieldsets = ['basic', 'description']; + echo JLayoutHelper::render('joomla.edit.params', $this); + ?> + + + + hidden_fields; ?> + + + + form->getInput('module'); ?> + form->getInput('client_id'); ?> + + config->show_switch) : ?> +
+ +
+ +
+
diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/views/module/tmpl/edit_assignment.php b/deployed/regularlabs/administrator/components/com_advancedmodules/views/module/tmpl/edit_assignment.php new file mode 100644 index 00000000..647c5475 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/views/module/tmpl/edit_assignment.php @@ -0,0 +1,80 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use RegularLabs\Library\Extension as RL_Extension; + +jimport('joomla.filesystem.file'); + +$this->config->show_assignto_groupusers = (int) ( + $this->config->show_assignto_usergrouplevels +); + + +$assignments = [ + 'menuitems', + 'homepage', + 'date', + 'groupusers', + 'languages', + 'templates', + 'urls', + 'devices', + 'os', + 'browsers', + 'components', + 'tags', + 'content', +]; +foreach ($assignments as $i => $ass) +{ + if ($ass != 'menuitems' && ( ! isset($this->config->{'show_assignto_' . $ass}) || ! $this->config->{'show_assignto_' . $ass})) + { + unset($assignments[$i]); + } +} + +$html = []; + +$html[] = $this->render($this->assignments, 'assignments'); + +$html[] = $this->render($this->assignments, 'mirror_module'); +$html[] = '
'; +$html[] = '
'; + +if (count($assignments) > 1) +{ + $html[] = $this->render($this->assignments, 'match_method'); + $html[] = $this->render($this->assignments, 'show_assignments'); +} +else +{ + $html[] = ''; +} + +foreach ($assignments as $ass) +{ + $html[] = $this->render($this->assignments, 'assignto_' . $ass); +} + +$show_assignto_users = 0; +$html[] = ''; +$html[] = ''; + +$html[] = '
'; + +echo implode("\n\n", $html); diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/views/module/tmpl/edit_options.php b/deployed/regularlabs/administrator/components/com_advancedmodules/views/module/tmpl/edit_options.php new file mode 100644 index 00000000..16e3dd3e --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/views/module/tmpl/edit_options.php @@ -0,0 +1,45 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; +?> + 'collapse0']); +$fieldSets = $this->form->getFieldsets('params'); +$i = 0; + +foreach ($fieldSets as $name => $fieldSet) : + $label = ! empty($fieldSet->label) ? $fieldSet->label : 'COM_MODULES_' . $name . '_FIELDSET_LABEL'; + $class = ! empty($fieldSet->class) ? $fieldSet->class : ''; + + echo JHtml::_('bootstrap.addSlide', 'moduleOptions', JText::_($label), 'collapse' . ($i++), $class); + if (isset($fieldSet->description) && trim($fieldSet->description)) : + echo '

' . $this->escape(JText::_($fieldSet->description)) . '

'; + endif; + ?> + form->getFieldset($name) as $field) : ?> +
+
+ label; ?> +
+
+ input; ?> +
+
+item->client_id; +$state = 1; +$selectedPosition = $this->item->position; +$positions = JHtml::_('modules.positions', $clientId, $state, $selectedPosition); + +// Add custom position to options +$customGroupText = JText::_('COM_MODULES_CUSTOM_POSITION'); + +// Build field +$attr = [ + 'id' => 'jform_position', + 'list.select' => $this->item->position, + 'list.attr' => 'class="chzn-custom-value" ' + . 'data-custom_group_text="' . $customGroupText . '" ' + . 'data-no_results_text="' . JText::_('COM_MODULES_ADD_CUSTOM_POSITION') . '" ' + . 'data-placeholder="' . JText::_('COM_MODULES_TYPE_OR_SELECT_POSITION') . '" ', +]; + +echo JHtml::_('select.groupedlist', $positions, 'jform[position]', $attr); diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/views/module/tmpl/modal.php b/deployed/regularlabs/administrator/components/com_advancedmodules/views/module/tmpl/modal.php new file mode 100644 index 00000000..dafd331c --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/views/module/tmpl/modal.php @@ -0,0 +1,33 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; +?> +
+
+ +
+
+ +
+
+
+ +setLayout('edit'); +echo $this->loadTemplate(); diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/views/module/view.html.php b/deployed/regularlabs/administrator/components/com_advancedmodules/views/module/view.html.php new file mode 100644 index 00000000..b28c682e --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/views/module/view.html.php @@ -0,0 +1,204 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use RegularLabs\Library\Parameters as RL_Parameters; +use RegularLabs\Library\RegEx as RL_RegEx; +use RegularLabs\Library\StringHelper as RL_String; + +/** + * View to edit a module. + */ +class AdvancedModulesViewModule extends JViewLegacy +{ + protected $form; + + protected $item; + + protected $state; + + /** + * Display the view + * + * @param string $tpl The name of the template file to parse; automatically searches through the template paths. + * + * @return void + */ + public function display($tpl = null) + { + $this->form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->state = $this->get('State'); + $this->canDo = JHelperContent::getActions('com_modules', 'module', $this->item->id); + $this->getConfig(); + $this->getAssignments(); + + if ( ! isset($this->item->published) || $this->item->published == '') + { + $this->item->published = $this->config->default_state; + } + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + if (RL_RegEx::match('_gk[1-9]', $this->item->module)) + { + + // Set message for Gavick modules + JFactory::getApplication()->enqueueMessage(JText::sprintf(RL_String::html_entity_decoder(JText::_('AMM_MODULE_INCOMPATIBLE')), '', ''), 'warning'); + } + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Function that gets the config settings + * + * @return Object + */ + protected function getConfig() + { + if (isset($this->config)) + { + return $this->config; + } + + $this->config = RL_Parameters::getInstance()->getComponentParams('advancedmodules'); + + return $this->config; + } + + /** + * Function that gets the config settings + * + * @return Object + */ + protected function getAssignments() + { + if ( ! isset($this->assignments)) + { + $xmlfile = JPATH_ADMINISTRATOR . '/components/com_advancedmodules/assignments.xml'; + $assignments = new JForm('assignments', ['control' => 'advancedparams']); + $assignments->loadFile($xmlfile, 1, '//config'); + $assignments->bind($this->item->advancedparams); + $this->assignments = $assignments; + } + + return $this->assignments; + } + + /** + * Add the page title and toolbar. + * + * @return void + */ + protected function addToolbar() + { + JFactory::getApplication()->input->set('hidemainmenu', true); + + $user = JFactory::getUser(); + $isNew = ($this->item->id == 0); + $checkedOut = ! ($this->item->checked_out == 0 || $this->item->checked_out == $user->get('id')); + $canDo = $this->canDo; + + $title = $this->item->title . ' [' . $this->item->module . ']'; + JToolbarHelper::title(JText::sprintf('AMM_MODULE_EDIT', $title), 'advancedmodulemanager icon-reglab'); + + // For new records, check the create permission. + if ($isNew && $canDo->get('core.create')) + { + JToolbarHelper::apply('module.apply'); + JToolbarHelper::save('module.save'); + JToolbarHelper::save2new('module.save2new'); + JToolbarHelper::cancel('module.cancel'); + } + else + { + // Can't save the record if it's checked out. + if ( ! $checkedOut) + { + // Since it's an existing record, check the edit permission. + if ($canDo->get('core.edit')) + { + JToolbarHelper::apply('module.apply'); + JToolbarHelper::save('module.save'); + + // We can save this record, but check the create permission to see if we can return to make a new one. + if ($canDo->get('core.create')) + { + JToolbarHelper::save2new('module.save2new'); + } + } + } + + // If checked out, we can still save + if ($canDo->get('core.create')) + { + JToolbarHelper::save2copy('module.save2copy'); + } + + JToolbarHelper::cancel('module.cancel', 'JTOOLBAR_CLOSE'); + } + + $tmpl = JFactory::getApplication()->input->get('tmpl'); + if ($tmpl != 'component') + { + // Get the help information for the menu item. + $lang = JFactory::getLanguage(); + + $help = $this->get('Help'); + + if ($lang->hasKey($help->url)) + { + $debug = $lang->setDebug(false); + $url = JText::_($help->url); + $lang->setDebug($debug); + } + else + { + $url = null; + } + + JToolbarHelper::help($help->key, false, $url); + } + } + + protected function render(&$form, $name = '') + { + $items = []; + + foreach ($form->getFieldset($name) as $field) + { + $items[] = '
' + . $field->label + . '
' + . $field->input + . '
'; + } + + if (empty ($items)) + { + return ''; + } + + return implode('', $items); + } +} diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/views/module/view.json.php b/deployed/regularlabs/administrator/components/com_advancedmodules/views/module/view.json.php new file mode 100644 index 00000000..63d3a2c0 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/views/module/view.json.php @@ -0,0 +1,64 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * View to edit a module. + * + * @package Joomla.Administrator + * @subpackage com_templates + * @since 3.2 + */ +class AdvancedModulesViewModule extends JViewLegacy +{ + protected $item; + + protected $form; + + protected $state; + + /** + * Display the view + * + * @param string $tpl The name of the template file to parse; automatically searches through the template paths. + * + * @return void + */ + public function display($tpl = null) + { + $app = JFactory::getApplication(); + + try + { + $this->item = $this->get('Item'); + } + catch (Exception $e) + { + $app->enqueueMessage($e->getMessage(), 'error'); + + return false; + } + + $paramsList = $this->item->getProperties(); + + unset($paramsList['xml']); + + $paramsList = json_encode($paramsList); + + return $paramsList; + } +} diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/tmpl/default.php b/deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/tmpl/default.php new file mode 100644 index 00000000..cf2d0fc9 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/tmpl/default.php @@ -0,0 +1,403 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use RegularLabs\Library\Document as RL_Document; +use RegularLabs\Library\License as RL_License; +use RegularLabs\Library\Version as RL_Version; + +JHtml::_('bootstrap.tooltip'); +JHtml::_('behavior.multiselect'); +JHtml::_('formbehavior.chosen', 'select'); + +$client = $this->state->get('filter.client_id') ? 'administrator' : 'site'; +$user = JFactory::getUser(); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$trashed = $this->state->get('filter.state') == -2 ? true : false; +$canOrder = $user->authorise('core.edit.state', 'com_modules'); +$saveOrder = ($listOrder == 'ordering'); + +$langs = JLanguage::getKnownLanguages(constant('JPATH_' . strtoupper($client))); + +if ($saveOrder) +{ + $saveOrderingUrl = 'index.php?option=com_advancedmodules&task=modules.saveOrderAjax&tmpl=component'; + JHtml::_('sortablelist.sortable', 'moduleList', 'adminForm', strtolower($listDirn), $saveOrderingUrl); +} + +$showcolors = ($client == 'site' && $this->config->show_color); +if ($showcolors) +{ + $script = " + function setColor(id, el) { + var f = document.getElementById('adminForm'); + f.setcolor.value = jQuery(el).val(); + listItemTask(id, 'modules.setcolor'); + } + "; + RL_Document::scriptDeclaration($script); +} + +RL_Document::style('regularlabs/style.min.css'); +?> +
+ sidebar)) : ?> +
+ sidebar; ?> +
+ +
sidebar)) ? ' class="span10"' : ''; ?>> + config->show_update_notification) + { + echo RL_Version::getMessage('ADVANCED_MODULE_MANAGER'); + } + ?> +
+ $this]); + $searchtool = str_replace( + '
+ +
+ + + + + + + + + + + + + + config->show_note == 3) : ?> + + + + + + + config->show_category) : ?> + + + + + + + + + + + + + + + + items as $i => $item) : ?> + authorise('core.create', 'com_modules'); + $canEdit = $user->authorise('core.edit', 'com_modules.module.' . $item->id); + $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id') || $item->checked_out == 0; + $canChange = $user->authorise('core.edit.state', 'com_modules.module.' . $item->id) && $canCheckin; + ?> + + + + + + + + + config->show_note == 3) : ?> + + + + + + config->show_category) : ?> + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ pagination->getListFooter(); ?> +
+ + + + + + + + + enabled > 0) : ?> + id); ?> + + +
+ + enabled > 0) : ?> + published, $i, 'modules.', $canChange, 'cb', $item->publish_up, $item->publish_down); ?> + escape($item->title)); + ?> + + + + +
+
+ params->color) && $item->params->color) + ? $color = str_replace('##', '#', $item->params->color) + : 'none'; + + $onchange = 'setColor(\'cb' . $i . '\', this)'; + + // For J3.7+ the onchange value needs to actually contain the onchange attribute name... nuts! + if (JVERSION >= 3.7) + { + $onchange = ' onchange="' . $onchange . '"'; + } + + $element = new SimpleXMLElement( + '' + ); + + $element->value = $color; + + $colorfield->setup($element, $color); + + echo $colorfield->__get('input'); + ?> + +
+ position) : ?> + + position; ?> + + + + + + +
+ +
+ checked_out) : ?> + editor, $item->checked_out_time, 'modules.', $canCheckin); ?> + + escape($item->title); + $tooltip = '' . JText::_('AMM_EDIT_MODULE') . '
' . htmlspecialchars($title); + if ( ! empty($item->note) && $this->config->show_note == 1) + { + $tooltip .= '
' . htmlspecialchars($this->escape($item->note)) . ''; + } + $title = '' . $title . ''; + ?> + + + + + + +
+ + name; ?> + +
+ + note) && $this->config->show_note == 2) : ?> +
+ escape($item->note); ?> +
+ +
+
+ escape($item->note); ?> + + position) : ?> + + position; ?> + + + + + + + + name; ?> + + category; ?> + + menuid; ?> + + escape($item->access_level); ?> + + language)) + { + echo JText::_('JDEFAULT'); + } + elseif ($item->language == '*') + { + $advanced_params = json_decode($item->advancedparams); + + if ( ! empty($advanced_params->assignto_languages) && $advanced_params->assignto_languages == 2) + { + $text = JText::_('COM_MODULES_ASSIGNED_VARIES_EXCEPT'); + } + else if ( ! empty($advanced_params->assignto_languages) && ! empty($advanced_params->assignto_languages_selection)) + { + $text = JText::_('COM_MODULES_ASSIGNED_VARIES_ONLY'); + } + else + { + $text = JText::alt('JALL', 'language'); + } + + echo $text; + } + else + { + echo $item->language_title + ? JHtml::_('image', 'mod_languages/' . $item->language_image . '.gif', $item->language_title, ['title' => $item->language_title], true) . ' ' . $this->escape($item->language_title) + : ((isset($langs[$item->language]) && ! empty($langs[$item->language]['name'])) + ? $this->escape($langs[$item->language]['name']) + : JText::_('JUNDEFINED') + ); + } + ?> + + id; ?> +
+ + + + authorise('core.create', 'com_modules') + && $user->authorise('core.edit', 'com_modules') + && $user->authorise('core.edit.state', 'com_modules') + ) : ?> + JText::_('COM_MODULES_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer'), + ], + $this->loadTemplate('batch_body') + ); ?> + + + + + + + + config->show_switch) : ?> +
+ +
+ + +
+
diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/tmpl/default.xml b/deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/tmpl/default.xml new file mode 100644 index 00000000..4d323670 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/tmpl/default_batch.php b/deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/tmpl/default_batch.php new file mode 100644 index 00000000..4b64a47d --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/tmpl/default_batch.php @@ -0,0 +1,78 @@ +state->get('filter.client_id'); + +// Show only Module Positions of published Templates +$published = 1; +$positions = JHtml::_('modules.positions', $clientId, $published); +$positions['']['items'][] = ModulesHelper::createOption('nochange', JText::_('COM_MODULES_BATCH_POSITION_NOCHANGE')); +$positions['']['items'][] = ModulesHelper::createOption('noposition', JText::_('COM_MODULES_BATCH_POSITION_NOPOSITION')); + +// Add custom position to options +$customGroupText = JText::_('COM_MODULES_CUSTOM_POSITION'); + +// Build field +$attr = [ + 'id' => 'batch-position-id', + 'list.attr' => 'class="chzn-custom-value input-xlarge" ' + . 'data-custom_group_text="' . $customGroupText . '" ' + . 'data-no_results_text="' . JText::_('COM_MODULES_ADD_CUSTOM_POSITION') . '" ' + . 'data-placeholder="' . JText::_('COM_MODULES_TYPE_OR_SELECT_POSITION') . '" ', +]; + +?> + diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/tmpl/default_batch_body.php b/deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/tmpl/default_batch_body.php new file mode 100644 index 00000000..9e295218 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/tmpl/default_batch_body.php @@ -0,0 +1,62 @@ +state->get('filter.client_id'); + +// Show only Module Positions of published Templates +$published = 1; +$positions = JHtml::_('modules.positions', $clientId, $published); +$positions['']['items'][] = ModulesHelper::createOption('nochange', JText::_('COM_MODULES_BATCH_POSITION_NOCHANGE')); +$positions['']['items'][] = ModulesHelper::createOption('noposition', JText::_('COM_MODULES_BATCH_POSITION_NOPOSITION')); + +// Add custom position to options +$customGroupText = JText::_('COM_MODULES_CUSTOM_POSITION'); + +// Build field +$attr = [ + 'id' => 'batch-position-id', + 'list.attr' => 'class="chzn-custom-value input-xlarge" ' + . 'data-custom_group_text="' . $customGroupText . '" ' + . 'data-no_results_text="' . JText::_('COM_MODULES_ADD_CUSTOM_POSITION') . '" ' + . 'data-placeholder="' . JText::_('COM_MODULES_TYPE_OR_SELECT_POSITION') . '" ', +]; + +?> + +

+
+
+
+ +
+
+
+
+ +
+
+
+
+ = 0) : ?> +
+
+ + +
+ +
+ +
+
+
+
+ +
diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/tmpl/default_batch_footer.php b/deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/tmpl/default_batch_footer.php new file mode 100644 index 00000000..9aa91749 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/tmpl/default_batch_footer.php @@ -0,0 +1,18 @@ + + + + + diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/tmpl/modal.php b/deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/tmpl/modal.php new file mode 100644 index 00000000..2046f1b3 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/tmpl/modal.php @@ -0,0 +1,165 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +if (JFactory::getApplication()->isClient('site')) +{ + JSession::checkToken('get') or die(JText::_('JINVALID_TOKEN')); +} + +use RegularLabs\Library\Document as RL_Document; + +JHtml::_('behavior.core'); +JHtml::_('bootstrap.tooltip', '.hasTooltip', ['placement' => 'bottom']); +JHtml::_('bootstrap.popover', '.hasPopover', ['placement' => 'bottom']); +JHtml::_('formbehavior.chosen', 'select'); + +// Special case for the search field tooltip. +$searchFilterDesc = $this->filterForm->getFieldAttribute('search', 'description', null, 'filter'); +JHtml::_('bootstrap.tooltip', '#filter_search', ['title' => JText::_($searchFilterDesc), 'placement' => 'bottom']); + +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$editor = JFactory::getApplication()->input->get('editor', '', 'cmd'); + +RL_Document::scriptDeclaration(' +moduleIns = function(type, name) { + window.parent.jInsertEditorText("{loadmodule " + type + "," + name + "}", "' . $editor . '"); + window.parent.jModalClose(); +}; +modulePosIns = function(position) { + window.parent.jInsertEditorText("{loadposition " + position + "}", "' . $editor . '"); + window.parent.jModalClose(); +};'); + +$link = 'index.php?option=com_advancedmodules&view=modules&layout=modal&tmpl=component&' . JSession::getFormToken() . '=1'; + +if ( ! empty($editor)) +{ + $link .= '&editor=' . $editor; +} + +$link .= '&' . JSession::getFormToken() . '=1'; + +?> +
+ +
+ + $this]); ?> + +
+ + items)) : ?> +
+ +
+ + + + + + + + + + + + + + + + + + + + + 'icon-trash', + 0 => 'icon-unpublish', + 1 => 'icon-publish', + 2 => 'icon-archive', + ]; + foreach ($this->items as $i => $item) : + ?> + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ pagination->getListFooter(); ?> +
+ + + escape($item->title); ?> + + position) : ?> + escape($item->position); ?> + + + + + name; ?> + + pages; ?> + + escape($item->access_level); ?> + + language == '') : ?> + + language == '*') : ?> + + + language_title ? JHtml::_('image', 'mod_languages/' . $item->language_image . '.gif', $item->language_title, ['title' => $item->language_title], true) . ' ' . $this->escape($item->language_title) : JText::_('JUNDEFINED'); ?> + + + id; ?> +
+ + + + + + + +
+
diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/view.html.php b/deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/view.html.php new file mode 100644 index 00000000..2154adcc --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/views/modules/view.html.php @@ -0,0 +1,215 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use RegularLabs\Library\Parameters as RL_Parameters; + +/** + * View class for a list of modules. + */ +class AdvancedModulesViewModules extends JViewLegacy +{ + protected $items; + + protected $pagination; + + protected $state; + + /** + * Display the view + * + * @param string $tpl The name of the template file to parse; automatically searches through the template paths. + * + * @return void + */ + public function display($tpl = null) + { + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + $this->getConfig(); + + foreach ($this->items as $i => $item) + { + $this->items[$i]->params = json_decode($item->advancedparams); + if (is_null($this->items[$i]->params)) + { + $this->items[$i]->params = (object) []; + } + } + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + if (JFactory::getApplication()->input->get('layout') != 'modal') + { + $this->addToolbar(); + } + + // Include the component HTML helpers. + JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + parent::display($tpl); + } + + /** + * Function that gets the config settings + * + * @return Object + */ + protected function getConfig() + { + if (isset($this->config)) + { + return $this->config; + } + + $this->config = RL_Parameters::getInstance()->getComponentParams('advancedmodules'); + + return $this->config; + } + + /** + * Add the page title and toolbar. + * + * @return void + */ + protected function addToolbar() + { + + $state = $this->get('State'); + $canDo = JHelperContent::getActions('com_modules'); + $user = JFactory::getUser(); + + // Get the toolbar object instance + $bar = JToolbar::getInstance('toolbar'); + + if ($this->config->list_title) + { + JToolbarHelper::title( + JText::_( + $state->get('filter.client_id') ? 'COM_MODULES_MANAGER_MODULES_ADMIN' : 'COM_MODULES_MANAGER_MODULES_SITE' + ), + 'cube module' + ); + } + else + { + JToolbarHelper::title( + JText::_('AMM_ADVANCED_MODULE_MANAGER'), + 'advancedmodulemanager icon-reglab' + ); + } + + if ($canDo->get('core.create')) + { + // Instantiate a new JLayoutFile instance and render the layout + $layout = new JLayoutFile('toolbar.newmodule'); + + $bar->appendButton('Custom', $layout->render([]), 'new'); + } + + if ($canDo->get('core.edit')) + { + JToolbarHelper::editList('module.edit'); + } + + if ($canDo->get('core.create')) + { + JToolbarHelper::custom('modules.duplicate', 'copy', 'copy_f2', 'JTOOLBAR_DUPLICATE', true); + } + + if ($canDo->get('core.edit.state')) + { + JToolbarHelper::publish('modules.publish', 'JTOOLBAR_PUBLISH', true); + JToolbarHelper::unpublish('modules.unpublish', 'JTOOLBAR_UNPUBLISH', true); + JToolbarHelper::checkin('modules.checkin'); + } + + if ($state->get('filter.state') == -2 && $canDo->get('core.delete')) + { + JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'modules.delete', 'JTOOLBAR_EMPTY_TRASH'); + } + elseif ($canDo->get('core.edit.state')) + { + JToolbarHelper::trash('modules.trash'); + } + + // Add a batch button + if ($user->authorise('core.create', 'com_modules') + && $user->authorise('core.edit', 'com_modules') + && $user->authorise('core.edit.state', 'com_modules') + ) + { + JHtml::_('bootstrap.modal', 'collapseModal'); + $title = JText::_('JTOOLBAR_BATCH'); + + // Instantiate a new JLayoutFile instance and render the batch button + $layout = new JLayoutFile('joomla.toolbar.batch'); + + $dhtml = $layout->render(['title' => $title]); + $bar->appendButton('Custom', $dhtml, 'batch'); + } + + if ($canDo->get('core.admin')) + { + JToolbarHelper::preferences('com_advancedmodules', 600, 900); + } + + JToolbarHelper::help('JHELP_EXTENSIONS_MODULE_MANAGER'); + } + + /** + * Returns an array of fields the table can be sorted by + * + * @return array Array containing the field name to sort by as the key and display text as value + */ + protected function getSortFields() + { + $fields = [ + 'ordering' => JText::_('JGRID_HEADING_ORDERING'), + 'a.published' => JText::_('JSTATUS'), + 'color' => JText::_('AMM_COLOR'), + 'a.title' => JText::_('JGLOBAL_TITLE'), + 'position' => JText::_('COM_MODULES_HEADING_POSITION'), + 'name' => JText::_('COM_MODULES_HEADING_MODULE'), + 'menuid' => JText::_('RL_MENU_ITEMS'), + 'a.access' => JText::_('JGRID_HEADING_ACCESS'), + 'language_title' => JText::_('JGRID_HEADING_LANGUAGE'), + 'a.id' => JText::_('JGRID_HEADING_ID'), + ]; + + if ($this->getLayout() != 'default') + { + unset($fields['ordering']); + unset($fields['a.published']); + unset($fields['color']); + } + + if ($this->state->get('filter.client_id') != 'site') + { + unset($fields['menuid']); + } + + return $fields; + } +} diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/views/positions/tmpl/modal.php b/deployed/regularlabs/administrator/components/com_advancedmodules/views/positions/tmpl/modal.php new file mode 100644 index 00000000..1142c7ab --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/views/positions/tmpl/modal.php @@ -0,0 +1,115 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); +JHtml::_('formbehavior.chosen', 'select'); + +$function = JFactory::getApplication()->input->getCmd('function', 'jSelectPosition'); +$lang = JFactory::getLanguage(); +$ordering = $this->escape($this->state->get('list.ordering')); +$direction = $this->escape($this->state->get('list.direction')); +$clientId = $this->state->get('client_id'); +$state = $this->state->get('filter.state'); +$template = $this->state->get('filter.template'); +$type = $this->state->get('filter.type'); +?> +
+
+
+ + + + + +
+ +
+ + + + + +
+
+ + + + + + + + + + + + + + + items as $value => $templates) : ?> + + + + + + +
+ + + +
+ pagination->getListFooter(); ?> +
+ escape($value); ?> + + + +
    + $label): ?> +
  • hasKey($label) ? JText::sprintf('COM_MODULES_MODULE_TEMPLATE_POSITION', JText::_($template), JText::_($label)) : JText::_($template); ?>
  • + +
+
+ +
+ +
+ + + + + +
+
diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/views/positions/view.html.php b/deployed/regularlabs/administrator/components/com_advancedmodules/views/positions/view.html.php new file mode 100644 index 00000000..a3243149 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/views/positions/view.html.php @@ -0,0 +1,47 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * @since 1.6 + */ +class AdvancedModulesViewPositions extends JViewLegacy +{ + protected $items; + + protected $pagination; + + protected $state; + + /** + * Display the view + */ + public function display($tpl = null) + { + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + parent::display($tpl); + } +} diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/views/preview/tmpl/default.php b/deployed/regularlabs/administrator/components/com_advancedmodules/views/preview/tmpl/default.php new file mode 100644 index 00000000..b1f84067 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/views/preview/tmpl/default.php @@ -0,0 +1,38 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2017 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2016 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; +?> + + + + + + + + + + +
+ +
+ +
diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/views/preview/view.html.php b/deployed/regularlabs/administrator/components/com_advancedmodules/views/preview/view.html.php new file mode 100644 index 00000000..f40e772f --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/views/preview/view.html.php @@ -0,0 +1,37 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2017 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2016 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +jimport('joomla.application.component.view'); + +/** + * HTML View class for the Modules component + * + * @static + * @since 1.6 + */ +class AdvancedModulesViewPreview extends JViewLegacy +{ + public function display($tpl = null) + { + $editor = JFactory::getConfig()->get('editor'); + + $this->editor = JEditor::getInstance($editor); + + parent::display($tpl); + } +} diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/views/select/tmpl/default.php b/deployed/regularlabs/administrator/components/com_advancedmodules/views/select/tmpl/default.php new file mode 100644 index 00000000..4a3128f6 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/views/select/tmpl/default.php @@ -0,0 +1,53 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + +JHtml::_('bootstrap.popover'); +?> + +

+
    + items as &$item) : ?> + extension_id; + $name = $this->escape($item->name); + $desc = JHtml::_('string.truncate', ($this->escape($item->desc)), 200); + $short_desc = JHtml::_('string.truncate', ($this->escape($item->desc)), 90); + ?> + direction != "rtl") : ?> +
  • + + + + +
  • + +
  • + + + + +
  • + + +
+
diff --git a/deployed/regularlabs/administrator/components/com_advancedmodules/views/select/view.html.php b/deployed/regularlabs/administrator/components/com_advancedmodules/views/select/view.html.php new file mode 100644 index 00000000..385aeef3 --- /dev/null +++ b/deployed/regularlabs/administrator/components/com_advancedmodules/views/select/view.html.php @@ -0,0 +1,65 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * HTML View class for the Modules component + */ +class AdvancedModulesViewSelect extends JViewLegacy +{ + protected $state; + + protected $items; + + /** + * Display the view + */ + public function display($tpl = null) + { + $state = $this->get('State'); + $items = $this->get('Items'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->state = &$state; + $this->items = &$items; + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + */ + protected function addToolbar() + { + // Add page title + JToolbarHelper::title(JText::_('COM_MODULES_MANAGER_MODULES'), 'advancedmodulemanager icon-reglab'); + + // Get the toolbar object instance + $bar = JToolbar::getInstance('toolbar'); + + // Instantiate a new JLayoutFile instance and render the layout + $layout = new JLayoutFile('toolbar.cancelselect'); + + $bar->appendButton('Custom', $layout->render([]), 'new'); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/autoload.php b/deployed/regularlabs/libraries/regularlabs/autoload.php new file mode 100644 index 00000000..539f2dff --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/autoload.php @@ -0,0 +1,2 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Language\Text as JText; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_AccessLevel extends \RegularLabs\Library\Field +{ + public $type = 'AccessLevel'; + + protected function getInput() + { + $size = (int) $this->get('size'); + $multiple = $this->get('multiple'); + $show_all = $this->get('show_all'); + $use_names = $this->get('use_names'); + + return $this->selectListAjax( + $this->type, $this->name, $this->value, $this->id, + compact('size', 'multiple', 'show_all', 'use_names') + ); + } + + function getAjaxRaw(Registry $attributes) + { + $name = $attributes->get('name', $this->type); + $id = $attributes->get('id', strtolower($name)); + $value = $attributes->get('value', []); + $size = $attributes->get('size'); + $multiple = $attributes->get('multiple'); + + $options = $this->getOptions( + (bool) $attributes->get('show_all'), + (bool) $attributes->get('use_names') + ); + + return $this->selectList($options, $name, $value, $id, $size, $multiple); + } + + protected function getOptions($show_all = false, $use_names = false) + { + $options = $this->getAccessLevels($use_names); + + if ($show_all) + { + $option = (object) []; + $option->value = -1; + $option->text = '- ' . JText::_('JALL') . ' -'; + $option->disable = ''; + array_unshift($options, $option); + } + + return $options; + } + + protected function getAccessLevels($use_names = false) + { + $value = $use_names ? 'a.title' : 'a.id'; + + $query = $this->db->getQuery(true) + ->select($value . ' as value, a.title as text') + ->from('#__viewlevels AS a') + ->group('a.id') + ->order('a.ordering ASC'); + $this->db->setQuery($query); + + return $this->db->loadObjectList(); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/agents.php b/deployed/regularlabs/libraries/regularlabs/fields/agents.php new file mode 100644 index 00000000..1366ffb0 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/agents.php @@ -0,0 +1,192 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\HTML\HTMLHelper as JHtml; +use Joomla\CMS\Language\Text as JText; +use Joomla\Registry\Registry; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_Agents extends \RegularLabs\Library\Field +{ + public $type = 'Agents'; + + protected function getInput() + { + if ( ! is_array($this->value)) + { + $this->value = explode(',', $this->value); + } + + $size = (int) $this->get('size'); + $group = $this->get('group', 'os'); + + return $this->selectListSimpleAjax( + $this->type, $this->name, $this->value, $this->id, + compact('size', 'group') + ); + } + + function getAjaxRaw(Registry $attributes) + { + $name = $attributes->get('name', $this->type); + $id = $attributes->get('id', strtolower($name)); + $value = $attributes->get('value', []); + $size = $attributes->get('size'); + + $options = $this->getAgents( + $attributes->get('group') + ); + + return $this->selectListSimple($options, $name, $value, $id, $size, true); + } + + function getAgents($group = 'os') + { + $agents = []; + switch ($group) + { + /* OS */ + case 'os': + $agents[] = ['Windows (' . JText::_('JALL') . ')', 'Windows']; + $agents[] = ['Windows 10', 'Windows nt 10.0']; + $agents[] = ['Windows 8', 'Windows nt 6.2']; + $agents[] = ['Windows 7', 'Windows nt 6.1']; + $agents[] = ['Windows Vista', 'Windows nt 6.0']; + $agents[] = ['Windows Server 2003', 'Windows nt 5.2']; + $agents[] = ['Windows XP', 'Windows nt 5.1']; + $agents[] = ['Windows 2000 sp1', 'Windows nt 5.01']; + $agents[] = ['Windows 2000', 'Windows nt 5.0']; + $agents[] = ['Windows NT 4.0', 'Windows nt 4.0']; + $agents[] = ['Windows Me', 'Win 9x 4.9']; + $agents[] = ['Windows 98', 'Windows 98']; + $agents[] = ['Windows 95', 'Windows 95']; + $agents[] = ['Windows CE', 'Windows ce']; + $agents[] = ['Mac OS (' . JText::_('JALL') . ')', '#(Mac OS|Mac_PowerPC|Macintosh)#']; + $agents[] = ['Mac OSX (' . JText::_('JALL') . ')', 'Mac OS X']; + $agents[] = ['Mac OSX El Capitan', 'Mac OS X 10.11']; + $agents[] = ['Mac OSX Yosemite', 'Mac OS X 10.10']; + $agents[] = ['Mac OSX Mavericks', 'Mac OS X 10.9']; + $agents[] = ['Mac OSX Mountain Lion', 'Mac OS X 10.8']; + $agents[] = ['Mac OSX Lion', 'Mac OS X 10.7']; + $agents[] = ['Mac OSX Snow Leopard', 'Mac OS X 10.6']; + $agents[] = ['Mac OSX Leopard', 'Mac OS X 10.5']; + $agents[] = ['Mac OSX Tiger', 'Mac OS X 10.4']; + $agents[] = ['Mac OSX Panther', 'Mac OS X 10.3']; + $agents[] = ['Mac OSX Jaguar', 'Mac OS X 10.2']; + $agents[] = ['Mac OSX Puma', 'Mac OS X 10.1']; + $agents[] = ['Mac OSX Cheetah', 'Mac OS X 10.0']; + $agents[] = ['Mac OS (classic)', '#(Mac_PowerPC|Macintosh)#']; + $agents[] = ['Linux', '#(Linux|X11)#']; + $agents[] = ['Open BSD', 'OpenBSD']; + $agents[] = ['Sun OS', 'SunOS']; + $agents[] = ['QNX', 'QNX']; + $agents[] = ['BeOS', 'BeOS']; + $agents[] = ['OS/2', 'OS/2']; + break; + + /* Browsers */ + case 'browsers': + if ($this->get('simple') && $this->get('simple') !== 'false') + { + $agents[] = ['Chrome', 'Chrome']; + $agents[] = ['Firefox', 'Firefox']; + $agents[] = ['Edge', 'Edge']; + $agents[] = ['Internet Explorer', 'MSIE']; + $agents[] = ['Opera', 'Opera']; + $agents[] = ['Safari', 'Safari']; + break; + } + + $agents[] = ['Chrome (' . JText::_('JALL') . ')', 'Chrome']; + $agents[] = ['Chrome 61-70', '#Chrome/(6[1-9]|70)\.#']; + $agents[] = ['Chrome 51-60', '#Chrome/(5[1-9]|60)\.#']; + $agents[] = ['Chrome 41-50', '#Chrome/(4[1-9]|50)\.#']; + $agents[] = ['Chrome 31-40', '#Chrome/(3[1-9]|40)\.#']; + $agents[] = ['Chrome 21-30', '#Chrome/(2[1-9]|30)\.#']; + $agents[] = ['Chrome 11-20', '#Chrome/(1[1-9]|20)\.#']; + $agents[] = ['Chrome 1-10', '#Chrome/([1-9]|10)\.#']; + $agents[] = ['Firefox (' . JText::_('JALL') . ')', 'Firefox']; + $agents[] = ['Firefox 61-70', '#Firefox/(6[1-9]|70)\.#']; + $agents[] = ['Firefox 51-60', '#Firefox/(5[1-9]|60)\.#']; + $agents[] = ['Firefox 41-50', '#Firefox/(4[1-9]|50)\.#']; + $agents[] = ['Firefox 31-40', '#Firefox/(3[1-9]|40)\.#']; + $agents[] = ['Firefox 21-30', '#Firefox/(2[1-9]|30)\.#']; + $agents[] = ['Firefox 11-20', '#Firefox/(1[1-9]|20)\.#']; + $agents[] = ['Firefox 1-10', '#Firefox/([1-9]|10)\.#']; + $agents[] = ['Internet Explorer (' . JText::_('JALL') . ')', 'MSIE']; + $agents[] = ['Internet Explorer Edge', 'MSIE Edge']; // missing MSIE is added to agent string in assignments/agents.php + $agents[] = ['Edge 15', 'Edge/15']; + $agents[] = ['Edge 14', 'Edge/14']; + $agents[] = ['Edge 13', 'Edge/13']; + $agents[] = ['Edge 12', 'Edge/12']; + $agents[] = ['Internet Explorer 11', 'MSIE 11']; // missing MSIE is added to agent string in assignments/agents.php + $agents[] = ['Internet Explorer 10.6', 'MSIE 10.6']; + $agents[] = ['Internet Explorer 10.0', 'MSIE 10.0']; + $agents[] = ['Internet Explorer 10', 'MSIE 10.']; + $agents[] = ['Internet Explorer 9', 'MSIE 9.']; + $agents[] = ['Internet Explorer 8', 'MSIE 8.']; + $agents[] = ['Internet Explorer 7', 'MSIE 7.']; + $agents[] = ['Internet Explorer 1-6', '#MSIE [1-6]\.#']; + $agents[] = ['Opera (' . JText::_('JALL') . ')', 'Opera']; + $agents[] = ['Opera 51-60', '#Opera/(5[1-9]|60)\.#']; + $agents[] = ['Opera 41-50', '#Opera/(4[1-9]|50)\.#']; + $agents[] = ['Opera 31-40', '#Opera/(3[1-9]|40)\.#']; + $agents[] = ['Opera 21-30', '#Opera/(2[1-9]|30)\.#']; + $agents[] = ['Opera 11-20', '#Opera/(1[1-9]|20)\.#']; + $agents[] = ['Opera 1-10', '#Opera/([1-9]|10)\.#']; + $agents[] = ['Safari (' . JText::_('JALL') . ')', 'Safari']; + $agents[] = ['Safari 11', '#Version/11\..*Safari/#']; + $agents[] = ['Safari 10', '#Version/10\..*Safari/#']; + $agents[] = ['Safari 9', '#Version/9\..*Safari/#']; + $agents[] = ['Safari 8', '#Version/8\..*Safari/#']; + $agents[] = ['Safari 7', '#Version/7\..*Safari/#']; + $agents[] = ['Safari 6', '#Version/6\..*Safari/#']; + $agents[] = ['Safari 5', '#Version/5\..*Safari/#']; + $agents[] = ['Safari 4', '#Version/4\..*Safari/#']; + $agents[] = ['Safari 1-3', '#Version/[1-3]\..*Safari/#']; + break; + + /* Mobile browsers */ + case 'mobile': + $agents[] = [JText::_('JALL'), 'mobile']; + $agents[] = ['Android', 'Android']; + $agents[] = ['Android Chrome', '#Android.*Chrome#']; + $agents[] = ['Blackberry', 'Blackberry']; + $agents[] = ['IE Mobile', 'IEMobile']; + $agents[] = ['iPad', 'iPad']; + $agents[] = ['iPhone', 'iPhone']; + $agents[] = ['iPod Touch', 'iPod']; + $agents[] = ['NetFront', 'NetFront']; + $agents[] = ['Nokia', 'NokiaBrowser']; + $agents[] = ['Opera Mini', 'Opera Mini']; + $agents[] = ['Opera Mobile', 'Opera Mobi']; + $agents[] = ['UC Browser', 'UC Browser']; + break; + } + + $options = []; + foreach ($agents as $agent) + { + $option = JHtml::_('select.option', $agent[1], $agent[0]); + $options[] = $option; + } + + return $options; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/ajax.php b/deployed/regularlabs/libraries/regularlabs/fields/ajax.php new file mode 100644 index 00000000..3137ae14 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/ajax.php @@ -0,0 +1,63 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; +use Joomla\CMS\Language\Text as JText; +use RegularLabs\Library\Document as RL_Document; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_Ajax extends \RegularLabs\Library\Field +{ + public $type = 'Ajax'; + + protected function getInput() + { + RL_Document::loadMainDependencies(); + + $loading = "jQuery(\"#" . $this->id . "\").find(\"span\").attr(\"class\", \"icon-refresh icon-spin\");"; + $success = "jQuery(\"#" . $this->id . "\").find(\"span\").attr(\"class\", \"icon-ok\");" + . "if(data){jQuery(\"#message_" . $this->id . "\").addClass(\"alert alert-success alert-noclose alert-inline\").html(data);}"; + $error = "jQuery(\"#" . $this->id . "\").find(\"span\").attr(\"class\", \"icon-warning\");" + . "if(data){jQuery(\"#message_" . $this->id . "\").addClass(\"alert alert-danger alert-noclose alert-inline\").html(data);}"; + + $script = "function loadAjax" . $this->id . "() {" + . $loading + . "jQuery(\"#message_" . $this->id . "\").attr(\"class\", \"\").html(\"\");" + . "RegularLabsScripts.loadajax(" + . "'" . addslashes($this->get('url')) . "'," + . "'var data = data.trim();" + . "if(data == \"\" || data.substring(0,1) == \"+\") {" + . "data = data.replace(/^\\\\+/, \\'\\');" + . $success + . "} else {" + . $error + . "}'," + . "'" . $error . "'" + . ");" + . "}"; + JFactory::getDocument()->addScriptDeclaration($script); + + return + '' + . '
'; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/akeebasubs.php b/deployed/regularlabs/libraries/regularlabs/fields/akeebasubs.php new file mode 100644 index 00000000..272be3ca --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/akeebasubs.php @@ -0,0 +1,48 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_AkeebaSubs extends \RegularLabs\Library\FieldGroup +{ + public $type = 'AkeebaSubs'; + public $default_group = 'Levels'; + + protected function getInput() + { + if ($error = $this->missingFilesOrTables(['levels'])) + { + return $error; + } + + return $this->getSelectList(); + } + + function getLevels() + { + $query = $this->db->getQuery(true) + ->select('l.akeebasubs_level_id as id, l.title AS name, l.enabled as published') + ->from('#__akeebasubs_levels AS l') + ->where('l.enabled > -1') + ->order('l.title, l.akeebasubs_level_id'); + $this->db->setQuery($query); + $list = $this->db->loadObjectList(); + + return $this->getOptionsByList($list, ['id']); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/assignmentselection.php b/deployed/regularlabs/libraries/regularlabs/fields/assignmentselection.php new file mode 100644 index 00000000..10833dff --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/assignmentselection.php @@ -0,0 +1,118 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; +use Joomla\CMS\Language\Text as JText; +use RegularLabs\Library\StringHelper as RL_String; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +/** + * @deprecated 2018-10-30 Use ConditionSelection instead + */ +class JFormFieldRL_AssignmentSelection extends \RegularLabs\Library\Field +{ + public $type = 'AssignmentSelection'; + + protected function getLabel() + { + return ''; + } + + protected function getInput() + { + require_once __DIR__ . '/toggler.php'; + $toggler = new RLFieldToggler; + + $this->value = (int) $this->value; + $label = $this->get('label'); + $param_name = $this->get('name'); + $use_main_toggle = $this->get('use_main_toggle', 1); + $showclose = $this->get('showclose', 0); + + $html = []; + + if ( ! $label) + { + if ($use_main_toggle) + { + $html[] = $toggler->getInput(['div' => 1]); + } + + $html[] = $toggler->getInput(['div' => 1]); + + return '' . implode('', $html); + } + + $label = RL_String::html_entity_decoder(JText::_($label)); + + $html[] = ''; + if ($use_main_toggle) + { + $html[] = $toggler->getInput(['div' => 1, 'param' => 'show_assignments|' . $param_name, 'value' => '1|1,2']); + } + + $class = 'well well-small rl_well'; + if ($this->value === 1) + { + $class .= ' alert-success'; + } + else if ($this->value === 2) + { + $class .= ' alert-error'; + } + $html[] = '
'; + if ($showclose && JFactory::getUser()->authorise('core.admin')) + { + $html[] = ''; + } + + $html[] = '
'; + + $html[] = '
'; + $html[] = ''; + $html[] = '
'; + + $html[] = '
'; + $html[] = '
'; + + $onclick = ' onclick="RegularLabsForm.setToggleTitleClass(this, 0)"'; + $html[] = 'value) ? ' checked="checked"' : '') . $onclick . '>'; + $html[] = ''; + + $onclick = ' onclick="RegularLabsForm.setToggleTitleClass(this, 1)"'; + $html[] = 'value === 1) ? ' checked="checked"' : '') . $onclick . '>'; + $html[] = ''; + + $onclick = ' onclick="RegularLabsForm.setToggleTitleClass(this, 2)"'; + $onclick .= ' onload="RegularLabsForm.setToggleTitleClass(this, ' . $this->value . ', 7)"'; + $html[] = 'value === 2) ? ' checked="checked"' : '') . $onclick . '>'; + $html[] = ''; + + $html[] = '
'; + $html[] = '
'; + + $html[] = '
'; + $html[] = '
'; + + $html[] = $toggler->getInput(['div' => 1, 'param' => $param_name, 'value' => '1,2']); + $html[] = '
'; + + return '
' . implode('', $html); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/block.php b/deployed/regularlabs/libraries/regularlabs/fields/block.php new file mode 100644 index 00000000..dc65d51a --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/block.php @@ -0,0 +1,77 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_Block extends \RegularLabs\Library\Field +{ + public $type = 'Block'; + + protected function getLabel() + { + return ''; + } + + protected function getInput() + { + $title = $this->get('label'); + $description = $this->get('description'); + $class = $this->get('class'); + $showclose = $this->get('showclose', 0); + + $start = $this->get('start', 0); + $end = $this->get('end', 0); + + $html = []; + + if ($start || ! $end) + { + $html[] = '
'; + if (strpos($class, 'alert') !== false) + { + $html[] = '
'; + } + else + { + $html[] = '
'; + } + if ($showclose && JFactory::getUser()->authorise('core.admin')) + { + $html[] = ''; + } + if ($title) + { + $html[] = '

' . $this->prepareText($title) . '

'; + } + if ($description) + { + $html[] = '
' . $this->prepareText($description) . '
'; + } + $html[] = '
'; + } + + if ( ! $start && ! $end) + { + $html[] = '
'; + } + + return '
' . implode('', $html); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/checkbox.php b/deployed/regularlabs/libraries/regularlabs/fields/checkbox.php new file mode 100644 index 00000000..a9ad551b --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/checkbox.php @@ -0,0 +1,102 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; +use Joomla\CMS\Language\Text as JText; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_Checkbox extends \RegularLabs\Library\Field +{ + public $type = 'Checkbox'; + + protected function getInput() + { + $showcheckall = $this->get('showcheckall', 0); + + $checkall = ($this->value == '*'); + + if ( ! $checkall) + { + if ( ! is_array($this->value)) + { + $this->value = explode(',', $this->value); + } + } + + $options = []; + foreach ($this->element->children() as $option) + { + if ($option->getName() != 'option') + { + continue; + } + + $text = trim((string) $option); + $hasval = 0; + if (isset($option['value'])) + { + $val = (string) $option['value']; + $disabled = (int) $option['disabled']; + $hasval = 1; + } + if ($hasval) + { + $option = 'value)) + { + $option .= ' checked="checked"'; + } + if ($disabled) + { + $option .= ' disabled="disabled"'; + } + $option .= '> '; + } + else + { + $option = ''; + } + $options[] = $option; + } + + $options = implode('', $options); + + if ($showcheckall) + { + $js = " + jQuery(document).ready(function() { + RegularLabsForm.initCheckAlls('rl_checkall_" . $this->id . "', 'rl_" . $this->id . "'); + }); + "; + JFactory::getDocument()->addScriptDeclaration($js); + + $checker = ' ' . JText::_('JALL'); + + $options = $checker . '
' . $options; + } + $options .= ''; + + $html = []; + $html[] = '
'; + $html[] = $options; + $html[] = '
'; + + return implode('', $html); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/codeeditor.php b/deployed/regularlabs/libraries/regularlabs/fields/codeeditor.php new file mode 100644 index 00000000..bba2b374 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/codeeditor.php @@ -0,0 +1,75 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Editor\Editor as JEditor; +use Joomla\CMS\Factory as JFactory; +use Joomla\CMS\Plugin\PluginHelper as JPluginHelper; +use RegularLabs\Library\Document as RL_Document; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_CodeEditor extends \RegularLabs\Library\Field +{ + public $type = 'CodeEditor'; + + protected function getInput() + { + $width = $this->get('width', '100%'); + $height = $this->get('height', 400); + + $this->value = htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8'); + + $editor_plugin = JPluginHelper::getPlugin('editors', 'codemirror'); + + if (empty($editor_plugin)) + { + return + ''; + } + + RL_Document::script('regularlabs/codemirror.min.js'); + RL_Document::stylesheet('regularlabs/codemirror.min.css'); + + JFactory::getDocument()->addScriptDeclaration(" + jQuery(document).ready(function($) { + RegularLabsCodeMirror.init('" . $this->id . "'); + }); + "); + + JFactory::getDocument()->addStyleDeclaration(" + #rl_codemirror_" . $this->id . " .CodeMirror { + height: " . $height . "px; + min-height: " . min($height, '100') . "px; + } + "); + + return '
' + . JEditor::getInstance('codemirror')->display( + $this->name, $this->value, + $width, $height, + 80, 10, + false, + $this->id, null, null, + ['markerGutter' => false, 'activeLine' => true, 'class' => 'xxx'] + ) + . '
'; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/color.php b/deployed/regularlabs/libraries/regularlabs/fields/color.php new file mode 100644 index 00000000..21555841 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/color.php @@ -0,0 +1,68 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Form\FormField as JFormField; +use RegularLabs\Library\Document as RL_Document; +use RegularLabs\Library\RegEx as RL_RegEx; + +jimport('joomla.form.formfield'); + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_Color extends JFormField +{ + public $type = 'Color'; + + protected function getInput() + { + if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) + { + return null; + } + + $field = new RLFieldColor; + + return $field->getInput($this->name, $this->id, $this->value, $this->element->attributes()); + } +} + +class RLFieldColor +{ + function getInput($name, $id, $value, $params) + { + $this->name = $name; + $this->id = $id; + $this->value = $value; + $this->params = $params; + + $class = trim('rl_color minicolors ' . $this->get('class')); + $disabled = $this->get('disabled') ? ' disabled="disabled"' : ''; + + RL_Document::script('regularlabs/color.min.js'); + RL_Document::stylesheet('regularlabs/color.min.css'); + + $this->value = strtolower(RL_RegEx::replace('[^a-z0-9]', '', $this->value)); + + return ''; + } + + private function get($val, $default = '') + { + return (isset($this->params[$val]) && (string) $this->params[$val] != '') ? (string) $this->params[$val] : $default; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/colorpicker.php b/deployed/regularlabs/libraries/regularlabs/fields/colorpicker.php new file mode 100644 index 00000000..cadc87f0 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/colorpicker.php @@ -0,0 +1,138 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +jimport('joomla.form.formfield'); + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +use RegularLabs\Library\Document as RL_Document; + +class JFormFieldRL_ColorPicker extends JFormField +{ + public $type = 'ColorPicker'; + + protected function getInput() + { + if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) + { + return null; + } + + $field = new RLFieldColorPicker; + + return $field->getInput($this->name, $this->id, $this->value, $this->element->attributes()); + } +} + +class RLFieldColorPicker +{ + function getInput($name, $id, $value, $params) + { + $this->name = $name; + $this->id = $id; + $this->value = $value; + $this->params = $params; + $action = ''; + + if ($this->get('inlist', 0) && $this->get('action')) + { + $this->name = $name . $id; + $this->id = $name . $id; + $action = ' onchange="' . $this->get('action') . '"'; + } + + RL_Document::script('regularlabs/colorpicker.min.js'); + RL_Document::stylesheet('regularlabs/colorpicker.min.css'); + + $class = ' class="' . trim('nncolorpicker chzn-done ' . $this->get('class')) . '"'; + + $color = strtolower($this->value); + if ( ! $color || in_array($color, ['none', 'transparent'])) + { + $color = 'none'; + } + else if ($color[0] != '#') + { + $color = '#' . $color; + } + + $colors = $this->get('colors'); + if (empty($colors)) + { + $colors = [ + 'none', + '#049cdb', + '#46a546', + '#9d261d', + '#ffc40d', + '#f89406', + '#c3325f', + '#7a43b6', + '#ffffff', + '#999999', + '#555555', + '#000000', + ]; + } + else + { + $colors = explode(',', $colors); + } + + $split = (int) $this->get('split'); + if ( ! $split) + { + $count = count($colors); + if ($count % 5 == 0) + { + $split = 5; + } + else if ($count % 4 == 0) + { + $split = 4; + } + } + $split = $split ? $split : 3; + + $html = []; + $html[] = ''; + + return implode('', $html); + } + + private function get($val, $default = '') + { + if ( ! isset($this->params[$val]) || (string) $this->params[$val] == '') + { + return $default; + } + + return (string) $this->params[$val]; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/components.php b/deployed/regularlabs/libraries/regularlabs/fields/components.php new file mode 100644 index 00000000..97da5d30 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/components.php @@ -0,0 +1,127 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; +use Joomla\CMS\HTML\HTMLHelper as JHtml; +use Joomla\CMS\Language\Text as JText; +use Joomla\Registry\Registry; +use RegularLabs\Library\RegEx as RL_RegEx; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_Components extends \RegularLabs\Library\Field +{ + public $type = 'Components'; + + protected function getInput() + { + $size = (int) $this->get('size'); + + return $this->selectListSimpleAjax( + $this->type, $this->name, $this->value, $this->id, + compact('size') + ); + } + + function getAjaxRaw(Registry $attributes) + { + $name = $attributes->get('name', $this->type); + $id = $attributes->get('id', strtolower($name)); + $value = $attributes->get('value', []); + $size = $attributes->get('size'); + + $options = $this->getComponents(); + + return $this->selectListSimple($options, $name, $value, $id, $size, true); + } + + function getComponents() + { + $frontend = $this->get('frontend', 1); + $admin = $this->get('admin', 1); + + if ( ! $frontend && ! $admin) + { + return []; + } + + jimport('joomla.filesystem.folder'); + jimport('joomla.filesystem.file'); + + $query = $this->db->getQuery(true) + ->select('e.name, e.element') + ->from('#__extensions AS e') + ->where('e.type = ' . $this->db->quote('component')) + ->where('e.name != ""') + ->where('e.element != ""') + ->group('e.element') + ->order('e.element, e.name'); + $this->db->setQuery($query); + $components = $this->db->loadObjectList(); + + $comps = []; + $lang = JFactory::getLanguage(); + + foreach ($components as $i => $component) + { + if (empty($component->element)) + { + continue; + } + + $component_folder = ($frontend ? JPATH_SITE : JPATH_ADMINISTRATOR) . '/components/' . $component->element; + + // return if there is no main component folder + if ( ! JFolder::exists($component_folder)) + { + continue; + } + + // return if there is no view(s) folder + if ( ! JFolder::exists($component_folder . '/views') && ! JFolder::exists($component_folder . '/view')) + { + continue; + } + + if (strpos($component->name, ' ') === false) + { + // Load the core file then + // Load extension-local file. + $lang->load($component->element . '.sys', JPATH_BASE, null, false, false) + || $lang->load($component->element . '.sys', JPATH_ADMINISTRATOR . '/components/' . $component->element, null, false, false) + || $lang->load($component->element . '.sys', JPATH_BASE, $lang->getDefault(), false, false) + || $lang->load($component->element . '.sys', JPATH_ADMINISTRATOR . '/components/' . $component->element, $lang->getDefault(), false, false); + + $component->name = JText::_(strtoupper($component->name)); + } + + $comps[RL_RegEx::replace('[^a-z0-9_]', '', $component->name . '_' . $component->element)] = $component; + } + + ksort($comps); + + $options = []; + + foreach ($comps as $component) + { + $options[] = JHtml::_('select.option', $component->element, $component->name); + } + + return $options; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/conditionselection.php b/deployed/regularlabs/libraries/regularlabs/fields/conditionselection.php new file mode 100644 index 00000000..35ae8f7d --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/conditionselection.php @@ -0,0 +1,133 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; +use Joomla\CMS\Language\Text as JText; +use RegularLabs\Library\ShowOn as RL_ShowOn; +use RegularLabs\Library\StringHelper as RL_String; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_ConditionSelection extends \RegularLabs\Library\Field +{ + public $type = 'ConditionSelection'; + + protected function getLabel() + { + return ''; + } + + protected function getInput() + { + $this->value = (int) $this->value; + $label = $this->get('label'); + $param_name = $this->get('name'); + $use_main_switch = $this->get('use_main_switch', 1); + $showclose = $this->get('showclose', 0); + + $html = []; + + if ( ! $label) + { + if ($use_main_switch) + { + $html[] = $this->closeShowOn(); + } + + $html[] = $this->closeShowOn(); + + return '
' . implode('', $html); + } + + $label = RL_String::html_entity_decoder(JText::_($label)); + + $html[] = '
'; + + if ($use_main_switch) + { + $html[] = $this->openShowOn('show_conditions:1[OR]show_assignments:1[OR]' . $param_name . ':1,2'); + } + + $class = 'well well-small rl_well'; + if ($this->value === 1) + { + $class .= ' alert-success'; + } + else if ($this->value === 2) + { + $class .= ' alert-error'; + } + $html[] = '
'; + if ($showclose && JFactory::getUser()->authorise('core.admin')) + { + $html[] = ''; + } + + $html[] = '
'; + + $html[] = '
'; + $html[] = ''; + $html[] = '
'; + + $html[] = '
'; + $html[] = '
'; + + $onclick = ' onclick="RegularLabsForm.setToggleTitleClass(this, 0)"'; + $html[] = 'value) ? ' checked="checked"' : '') . $onclick . '>'; + $html[] = ''; + + $onclick = ' onclick="RegularLabsForm.setToggleTitleClass(this, 1)"'; + $html[] = 'value === 1) ? ' checked="checked"' : '') . $onclick . '>'; + $html[] = ''; + + $onclick = ' onclick="RegularLabsForm.setToggleTitleClass(this, 2)"'; + $onclick .= ' onload="RegularLabsForm.setToggleTitleClass(this, ' . $this->value . ', 7)"'; + $html[] = 'value === 2) ? ' checked="checked"' : '') . $onclick . '>'; + $html[] = ''; + + $html[] = '
'; + $html[] = '
'; + + $html[] = '
'; + $html[] = '
'; + + $html[] = $this->openShowOn($param_name . ':1,2'); + + $html[] = '
'; + + return '
' . implode('', $html); + } + + protected function openShowOn($condition = '') + { + if ( ! $condition) + { + return $this->closeShowon(); + } + + $formControl = $this->get('form', $this->formControl); + $formControl = $formControl == 'root' ? '' : $formControl; + + return RL_ShowOn::open($condition, $formControl); + } + + protected function closeShowOn() + { + return RL_ShowOn::close(); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/content.php b/deployed/regularlabs/libraries/regularlabs/fields/content.php new file mode 100644 index 00000000..81d9ba83 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/content.php @@ -0,0 +1,99 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\HTML\HTMLHelper as JHtml; +use Joomla\CMS\Language\Text as JText; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_Content extends \RegularLabs\Library\FieldGroup +{ + public $type = 'Content'; + + function getCategories() + { + $query = $this->db->getQuery(true) + ->select('COUNT(*)') + ->from('#__categories') + ->where('extension = ' . $this->db->quote('com_content')) + ->where('parent_id > 0') + ->where('published > -1'); + $this->db->setQuery($query); + $total = $this->db->loadResult(); + + if ($total > $this->max_list_count) + { + return -1; + } + + // assemble items to the array + $options = []; + if ($this->get('show_ignore')) + { + if (in_array('-1', $this->value)) + { + $this->value = ['-1']; + } + $options[] = JHtml::_('select.option', '-1', '- ' . JText::_('RL_IGNORE') . ' -'); + $options[] = JHtml::_('select.option', '-', ' ', 'value', 'text', true); + } + + $query->clear('select') + ->select('id, title as name, level, published, language') + ->order('lft'); + + $this->db->setQuery($query); + $list = $this->db->loadObjectList(); + + $options = array_merge($options, $this->getOptionsByList($list, ['language'], -1)); + + return $options; + } + + function getItems() + { + $query = $this->db->getQuery(true) + ->select('COUNT(*)') + ->from('#__content AS i') + ->where('i.access > -1'); + $this->db->setQuery($query); + $total = $this->db->loadResult(); + + if ($total > $this->max_list_count) + { + return -1; + } + + $query->clear('select') + ->select('i.id, i.title as name, i.language, c.title as cat, i.state as published') + ->join('LEFT', '#__categories AS c ON c.id = i.catid') + ->order('i.title, i.ordering, i.id'); + $this->db->setQuery($query); + $list = $this->db->loadObjectList(); + + $options = $this->getOptionsByList($list, ['language', 'cat', 'id']); + + if ($this->get('showselect')) + { + array_unshift($options, JHtml::_('select.option', '-', ' ', 'value', 'text', true)); + array_unshift($options, JHtml::_('select.option', '-', '- ' . JText::_('Select Item') . ' -')); + } + + return $options; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/customfieldkey.php b/deployed/regularlabs/libraries/regularlabs/fields/customfieldkey.php new file mode 100644 index 00000000..385d56c5 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/customfieldkey.php @@ -0,0 +1,46 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Language\Text as JText; +use RegularLabs\Library\StringHelper as RL_String; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_CustomFieldKey extends \RegularLabs\Library\Field +{ + public $type = 'CustomFieldKey'; + + protected function getLabel() + { + $label = $this->get('label') ? $this->get('label') : ''; + $size = $this->get('size') ? 'style="width:' . $this->get('size') . 'px"' : ''; + $class = 'class="' . ($this->get('class') ? $this->get('class') : 'text_area') . '"'; + $this->value = htmlspecialchars(RL_String::html_entity_decoder($this->value), ENT_QUOTES); + + return + ''; + } + + protected function getInput() + { + return '
'; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/customfieldvalue.php b/deployed/regularlabs/libraries/regularlabs/fields/customfieldvalue.php new file mode 100644 index 00000000..d869e0b8 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/customfieldvalue.php @@ -0,0 +1,45 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Language\Text as JText; +use RegularLabs\Library\StringHelper as RL_String; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_CustomFieldValue extends \RegularLabs\Library\Field +{ + public $type = 'CustomFieldValue'; + + protected function getLabel() + { + return ''; + } + + protected function getInput() + { + $label = $this->get('label') ? $this->get('label') : ''; + $size = $this->get('size') ? 'style="width:' . $this->get('size') . 'px"' : ''; + $class = 'class="' . ($this->get('class') ? $this->get('class') : 'text_area') . '"'; + $this->value = htmlspecialchars(RL_String::html_entity_decoder($this->value), ENT_QUOTES); + + return + '
' + . ''; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/datetime.php b/deployed/regularlabs/libraries/regularlabs/fields/datetime.php new file mode 100644 index 00000000..50ce3ef6 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/datetime.php @@ -0,0 +1,64 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; +use Joomla\CMS\Language\Text as JText; +use RegularLabs\Library\Date as RL_Date; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_DateTime extends \RegularLabs\Library\Field +{ + public $type = 'DateTime'; + + protected function getLabel() + { + return ''; + } + + protected function getInput() + { + $label = $this->get('label'); + $format = $this->get('format'); + + $date = JFactory::getDate(); + + $tz = new DateTimeZone(JFactory::getApplication()->getCfg('offset')); + $date->setTimeZone($tz); + + if ($format) + { + if (strpos($format, '%') !== false) + { + $format = RL_Date::strftimeToDateFormat($format); + } + $html = $date->format($format, true); + } + else + { + $html = $date->format('', true); + } + + if ($label) + { + $html = JText::sprintf($label, $html); + } + + return '
' . $html; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/dependency.php b/deployed/regularlabs/libraries/regularlabs/fields/dependency.php new file mode 100644 index 00000000..2deeafc9 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/dependency.php @@ -0,0 +1,112 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; +use Joomla\CMS\Language\Text as JText; +use RegularLabs\Library\RegEx as RL_RegEx; + +jimport('joomla.form.formfield'); + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_Dependency extends \RegularLabs\Library\Field +{ + public $type = 'Dependency'; + + protected function getLabel() + { + return ''; + } + + protected function getInput() + { + if ($file = $this->get('file')) + { + $label = $this->get('label', 'the main extension'); + + RLFieldDependency::setMessage($file, $label); + + return ''; + } + + $path = ($this->get('path') == 'site') ? '' : '/administrator'; + $label = $this->get('label'); + $file = $this->get('alias', $label); + $file = RL_RegEx::replace('[^a-z-]', '', strtolower($file)); + $extension = $this->get('extension'); + + switch ($extension) + { + case 'com'; + $file = $path . '/components/com_' . $file . '/com_' . $file . '.xml'; + break; + case 'mod'; + $file = $path . '/modules/mod_' . $file . '/mod_' . $file . '.xml'; + break; + default: + $file = '/plugins/' . str_replace('plg_', '', $extension) . '/' . $file . '.xml'; + break; + } + + $label = JText::_($label) . ' (' . JText::_('RL_' . strtoupper($extension)) . ')'; + + RLFieldDependency::setMessage($file, $label); + + return ''; + } +} + +class RLFieldDependency +{ + static function setMessage($file, $name) + { + jimport('joomla.filesystem.file'); + + $file = str_replace('\\', '/', $file); + if (strpos($file, '/administrator') === 0) + { + $file = str_replace('/administrator', JPATH_ADMINISTRATOR, $file); + } + else + { + $file = JPATH_SITE . '/' . $file; + } + $file = str_replace('//', '/', $file); + + $file_alt = RL_RegEx::replace('(com|mod)_([a-z-_]+\.)', '\2', $file); + + if ( ! JFile::exists($file) && ! JFile::exists($file_alt)) + { + $msg = JText::sprintf('RL_THIS_EXTENSION_NEEDS_THE_MAIN_EXTENSION_TO_FUNCTION', JText::_($name)); + $message_set = 0; + $messageQueue = JFactory::getApplication()->getMessageQueue(); + foreach ($messageQueue as $queue_message) + { + if ($queue_message['type'] == 'error' && $queue_message['message'] == $msg) + { + $message_set = 1; + break; + } + } + if ( ! $message_set) + { + JFactory::getApplication()->enqueueMessage($msg, 'error'); + } + } + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/easyblog.php b/deployed/regularlabs/libraries/regularlabs/fields/easyblog.php new file mode 100644 index 00000000..75245b3d --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/easyblog.php @@ -0,0 +1,86 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_EasyBlog extends \RegularLabs\Library\FieldGroup +{ + public $type = 'EasyBlog'; + + protected function getInput() + { + if ($error = $this->missingFilesOrTables(['categories' => 'category', 'items' => 'post', 'tags' => 'tag'])) + { + return $error; + } + + return $this->getSelectList(); + } + + function getCategories() + { + $query = $this->db->getQuery(true) + ->select('COUNT(*)') + ->from('#__easyblog_category AS c') + ->where('c.published > -1'); + $this->db->setQuery($query); + $total = $this->db->loadResult(); + + if ($total > $this->max_list_count) + { + return -1; + } + + $query->clear('select') + ->select('c.id, c.parent_id, c.title, c.published') + ->order('c.ordering, c.title'); + $this->db->setQuery($query); + $items = $this->db->loadObjectList(); + + return $this->getOptionsTreeByList($items); + } + + function getItems() + { + $query = $this->db->getQuery(true) + ->select('i.id, i.title as name, c.title as cat, i.published') + ->from('#__easyblog_post AS i') + ->join('LEFT', '#__easyblog_category AS c ON c.id = i.category_id') + ->where('i.published > -1') + ->order('i.title, c.title, i.id'); + $this->db->setQuery($query); + $list = $this->db->loadObjectList(); + + return $this->getOptionsByList($list, ['cat', 'id']); + } + + function getTags() + { + $query = $this->db->getQuery(true) + ->select('t.alias as id, t.title as name') + ->from('#__easyblog_tag AS t') + ->where('t.published > -1') + ->where('t.title != ' . $this->db->quote('')) + ->group('t.title') + ->order('t.title'); + $this->db->setQuery($query); + $list = $this->db->loadObjectList(); + + return $this->getOptionsByList($list); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/editor.php b/deployed/regularlabs/libraries/regularlabs/fields/editor.php new file mode 100644 index 00000000..48641cc4 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/editor.php @@ -0,0 +1,45 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_Editor extends \RegularLabs\Library\Field +{ + public $type = 'Editor'; + + protected function getLabel() + { + return ''; + } + + protected function getInput() + { + $width = $this->get('width', '100%'); + $height = $this->get('height', 400); + + $this->value = htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8'); + + // Get an editor object. + $editor = JFactory::getEditor(); + $html = $editor->display($this->name, $this->value, $width, $height, true, $this->id); + + return '
' . $html; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/filelist.php b/deployed/regularlabs/libraries/regularlabs/fields/filelist.php new file mode 100644 index 00000000..6a41fd09 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/filelist.php @@ -0,0 +1,112 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\HTML\HTMLHelper as JHtml; +use Joomla\CMS\Language\Text as JText; +use RegularLabs\Library\RegEx as RL_RegEx; + +jimport('joomla.filesystem.folder'); +jimport('joomla.filesystem.file'); + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +require_once JPATH_LIBRARIES . '/joomla/form/fields/list.php'; + +class JFormFieldRL_FileList extends JFormFieldList +{ + public $type = 'FileList'; + private $params = null; + + protected function getInput() + { + return parent::getInput(); + } + + protected function getOptions() + { + $options = []; + + $path = $this->get('folder'); + + if ( ! is_dir($path)) + { + $path = JPATH_ROOT . '/' . $path; + } + + // Prepend some default options based on field attributes. + if ( ! $this->get('hidenone', 0)) + { + $options[] = JHtml::_('select.option', '-1', JText::alt('JOPTION_DO_NOT_USE', + RL_RegEx::replace('[^a-z0-9_\-]', '_', $this->fieldname))); + } + + if ( ! $this->get('hidedefault', 0)) + { + $options[] = JHtml::_('select.option', '', JText::alt('JOPTION_USE_DEFAULT', + RL_RegEx::replace('[^a-z0-9_\-]', '_', $this->fieldname))); + } + + // Get a list of files in the search path with the given filter. + $files = JFolder::files($path, $this->get('filter')); + + // Build the options list from the list of files. + if (is_array($files)) + { + foreach ($files as $file) + { + // Check to see if the file is in the exclude mask. + if ($this->get('exclude')) + { + if (RL_RegEx::match(chr(1) . $this->get('exclude') . chr(1), $file)) + { + continue; + } + } + + // If the extension is to be stripped, do it. + if ($this->get('stripext', 1)) + { + $file = JFile::stripExt($file); + } + + $label = $file; + if ($this->get('language_prefix')) + { + $label = JText::_($this->get('language_prefix') . strtoupper($label)); + } + + $options[] = JHtml::_('select.option', $file, $label); + } + } + + // Merge any additional options in the XML definition. + $options = array_merge(parent::getOptions(), $options); + + return $options; + } + + private function get($val, $default = '') + { + if ( ! isset($this->params[$val]) || (string) $this->params[$val] == '') + { + return $default; + } + + return (string) $this->params[$val]; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/flexicontent.php b/deployed/regularlabs/libraries/regularlabs/fields/flexicontent.php new file mode 100644 index 00000000..3f98dc4b --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/flexicontent.php @@ -0,0 +1,63 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_FlexiContent extends \RegularLabs\Library\FieldGroup +{ + public $type = 'FlexiContent'; + public $default_group = 'Tags'; + + protected function getInput() + { + if ($error = $this->missingFilesOrTables(['tags', 'types'])) + { + return $error; + } + + return $this->getSelectList(); + } + + function getTags() + { + $query = $this->db->getQuery(true) + ->select('t.name as id, t.name') + ->from('#__flexicontent_tags AS t') + ->where('t.published = 1') + ->where('t.name != ' . $this->db->quote('')) + ->group('t.name') + ->order('t.name'); + $this->db->setQuery($query); + $list = $this->db->loadObjectList(); + + return $this->getOptionsByList($list); + } + + function getTypes() + { + $query = $this->db->getQuery(true) + ->select('t.id, t.name') + ->from('#__flexicontent_types AS t') + ->where('t.published = 1') + ->order('t.name, t.id'); + $this->db->setQuery($query); + $list = $this->db->loadObjectList(); + + return $this->getOptionsByList($list); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/form2content.php b/deployed/regularlabs/libraries/regularlabs/fields/form2content.php new file mode 100644 index 00000000..423b22d9 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/form2content.php @@ -0,0 +1,48 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_Form2Content extends \RegularLabs\Library\FieldGroup +{ + public $type = 'Form2Content'; + public $default_group = 'Projects'; + + protected function getInput() + { + if ($error = $this->missingFilesOrTables(['projects' => 'project'], '', 'f2c')) + { + return $error; + } + + return $this->getSelectList(); + } + + function getProjects() + { + $query = $this->db->getQuery(true) + ->select('t.id, t.title as name') + ->from('#__f2c_project AS t') + ->where('t.published = 1') + ->order('t.title, t.id'); + $this->db->setQuery($query); + $list = $this->db->loadObjectList(); + + return $this->getOptionsByList($list); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/geo.php b/deployed/regularlabs/libraries/regularlabs/fields/geo.php new file mode 100644 index 00000000..d04f4ba7 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/geo.php @@ -0,0 +1,2605 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\HTML\HTMLHelper as JHtml; +use Joomla\Registry\Registry; +use RegularLabs\Library\Form as RL_Form; +use RegularLabs\Library\RegEx as RL_RegEx; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_Geo extends \RegularLabs\Library\Field +{ + public $type = 'Geo'; + + protected function getInput() + { + + if ( ! is_array($this->value)) + { + $this->value = explode(',', $this->value); + } + + $size = (int) $this->get('size'); + $multiple = $this->get('multiple'); + $group = $this->get('group', 'countries'); + $use_names = $this->get('use_names', false); + + return $this->selectListSimpleAjax( + $this->type, $this->name, $this->value, $this->id, + compact('size', 'multiple', 'group', 'use_names') + ); + } + + function getAjaxRaw(Registry $attributes) + { + $name = $attributes->get('name', $this->type); + $id = $attributes->get('id', strtolower($name)); + $value = $attributes->get('value', []); + $size = $attributes->get('size'); + + $options = $this->getOptions( + $attributes->get('group', 'countries'), + (bool) $attributes->get('use_names', false) + ); + + return $this->selectListSimple($options, $name, $value, $id, $size, true); + } + + function getOptions($group = 'countries', $use_names = '') + { + $options = []; + foreach ($this->{$group} as $key => $val) + { + if ( ! $val) + { + $options[] = JHtml::_('select.option', '-', ' ', 'value', 'text', true); + continue; + } + + if ($key[0] == '-') + { + $options[] = JHtml::_('select.option', '-', $val, 'value', 'text', true); + continue; + } + + $val = RL_Form::prepareSelectItem($val); + $options[] = JHtml::_('select.option', $use_names ? $val : $key, $val); + } + + return $options; + } + + public $continents = [ + 'AF' => 'Africa', + 'AS' => 'Asia', + 'EU' => 'Europe', + 'NA' => 'North America', + 'SA' => 'South America', + 'OC' => 'Oceania', + 'AN' => 'Antarctica', + ]; + + public $countries = [ + 'AF' => "Afghanistan", + 'AX' => "Aland Islands", + 'AL' => "Albania", + 'DZ' => "Algeria", + 'AS' => "American Samoa", + 'AD' => "Andorra", + 'AO' => "Angola", + 'AI' => "Anguilla", + 'AQ' => "Antarctica", + 'AG' => "Antigua and Barbuda", + 'AR' => "Argentina", + 'AM' => "Armenia", + 'AW' => "Aruba", + 'AU' => "Australia", + 'AT' => "Austria", + 'AZ' => "Azerbaijan", + 'BS' => "Bahamas", + 'BH' => "Bahrain", + 'BD' => "Bangladesh", + 'BB' => "Barbados", + 'BY' => "Belarus", + 'BE' => "Belgium", + 'BZ' => "Belize", + 'BJ' => "Benin", + 'BM' => "Bermuda", + 'BT' => "Bhutan", + 'BO' => "Bolivia", + 'BA' => "Bosnia and Herzegovina", + 'BW' => "Botswana", + 'BV' => "Bouvet Island", + 'BR' => "Brazil", + 'IO' => "British Indian Ocean Territory", + 'BN' => "Brunei Darussalam", + 'BG' => "Bulgaria", + 'BF' => "Burkina Faso", + 'BI' => "Burundi", + 'KH' => "Cambodia", + 'CM' => "Cameroon", + 'CA' => "Canada", + 'CV' => "Cape Verde", + 'KY' => "Cayman Islands", + 'CF' => "Central African Republic", + 'TD' => "Chad", + 'CL' => "Chile", + 'CN' => "China", + 'CX' => "Christmas Island", + 'CC' => "Cocos (Keeling) Islands", + 'CO' => "Colombia", + 'KM' => "Comoros", + 'CG' => "Congo", + 'CD' => "Congo, The Democratic Republic of the", + 'CK' => "Cook Islands", + 'CR' => "Costa Rica", + 'CI' => "Cote d'Ivoire", + 'HR' => "Croatia", + 'CU' => "Cuba", + 'CY' => "Cyprus", + 'CZ' => "Czech Republic", + 'DK' => "Denmark", + 'DJ' => "Djibouti", + 'DM' => "Dominica", + 'DO' => "Dominican Republic", + 'EC' => "Ecuador", + 'EG' => "Egypt", + 'SV' => "El Salvador", + 'GQ' => "Equatorial Guinea", + 'ER' => "Eritrea", + 'EE' => "Estonia", + 'ET' => "Ethiopia", + 'FK' => "Falkland Islands (Malvinas)", + 'FO' => "Faroe Islands", + 'FJ' => "Fiji", + 'FI' => "Finland", + 'FR' => "France", + 'GF' => "French Guiana", + 'PF' => "French Polynesia", + 'TF' => "French Southern Territories", + 'GA' => "Gabon", + 'GM' => "Gambia", + 'GE' => "Georgia", + 'DE' => "Germany", + 'GH' => "Ghana", + 'GI' => "Gibraltar", + 'GR' => "Greece", + 'GL' => "Greenland", + 'GD' => "Grenada", + 'GP' => "Guadeloupe", + 'GU' => "Guam", + 'GT' => "Guatemala", + 'GG' => "Guernsey", + 'GN' => "Guinea", + 'GW' => "Guinea-Bissau", + 'GY' => "Guyana", + 'HT' => "Haiti", + 'HM' => "Heard Island and McDonald Islands", + 'VA' => "Holy See (Vatican City State)", + 'HN' => "Honduras", + 'HK' => "Hong Kong", + 'HU' => "Hungary", + 'IS' => "Iceland", + 'IN' => "India", + 'ID' => "Indonesia", + 'IR' => "Iran, Islamic Republic of", + 'IQ' => "Iraq", + 'IE' => "Ireland", + 'IM' => "Isle of Man", + 'IL' => "Israel", + 'IT' => "Italy", + 'JM' => "Jamaica", + 'JP' => "Japan", + 'JE' => "Jersey", + 'JO' => "Jordan", + 'KZ' => "Kazakhstan", + 'KE' => "Kenya", + 'KI' => "Kiribati", + 'KP' => "Korea, Democratic People's Republic of", + 'KR' => "Korea, Republic of", + 'KW' => "Kuwait", + 'KG' => "Kyrgyzstan", + 'LA' => "Lao People's Democratic Republic", + 'LV' => "Latvia", + 'LB' => "Lebanon", + 'LS' => "Lesotho", + 'LR' => "Liberia", + 'LY' => "Libyan Arab Jamahiriya", + 'LI' => "Liechtenstein", + 'LT' => "Lithuania", + 'LU' => "Luxembourg", + 'MO' => "Macao", + 'MK' => "Macedonia", + 'MG' => "Madagascar", + 'MW' => "Malawi", + 'MY' => "Malaysia", + 'MV' => "Maldives", + 'ML' => "Mali", + 'MT' => "Malta", + 'MH' => "Marshall Islands", + 'MQ' => "Martinique", + 'MR' => "Mauritania", + 'MU' => "Mauritius", + 'YT' => "Mayotte", + 'MX' => "Mexico", + 'FM' => "Micronesia, Federated States of", + 'MD' => "Moldova, Republic of", + 'MC' => "Monaco", + 'MN' => "Mongolia", + 'ME' => "Montenegro", + 'MS' => "Montserrat", + 'MA' => "Morocco", + 'MZ' => "Mozambique", + 'MM' => "Myanmar", + 'NA' => "Namibia", + 'NR' => "Nauru", + 'NP' => "Nepal", + 'NL' => "Netherlands", + 'AN' => "Netherlands Antilles", + 'NC' => "New Caledonia", + 'NZ' => "New Zealand", + 'NI' => "Nicaragua", + 'NE' => "Niger", + 'NG' => "Nigeria", + 'NU' => "Niue", + 'NF' => "Norfolk Island", + 'MP' => "Northern Mariana Islands", + 'NO' => "Norway", + 'OM' => "Oman", + 'PK' => "Pakistan", + 'PW' => "Palau", + 'PS' => "Palestinian Territory", + 'PA' => "Panama", + 'PG' => "Papua New Guinea", + 'PY' => "Paraguay", + 'PE' => "Peru", + 'PH' => "Philippines", + 'PN' => "Pitcairn", + 'PL' => "Poland", + 'PT' => "Portugal", + 'PR' => "Puerto Rico", + 'QA' => "Qatar", + 'RE' => "Reunion", + 'RO' => "Romania", + 'RU' => "Russian Federation", + 'RW' => "Rwanda", + 'SH' => "Saint Helena", + 'KN' => "Saint Kitts and Nevis", + 'LC' => "Saint Lucia", + 'PM' => "Saint Pierre and Miquelon", + 'VC' => "Saint Vincent and the Grenadines", + 'WS' => "Samoa", + 'SM' => "San Marino", + 'ST' => "Sao Tome and Principe", + 'SA' => "Saudi Arabia", + 'SN' => "Senegal", + 'RS' => "Serbia", + 'SC' => "Seychelles", + 'SL' => "Sierra Leone", + 'SG' => "Singapore", + 'SK' => "Slovakia", + 'SI' => "Slovenia", + 'SB' => "Solomon Islands", + 'SO' => "Somalia", + 'ZA' => "South Africa", + 'GS' => "South Georgia and the South Sandwich Islands", + 'ES' => "Spain", + 'LK' => "Sri Lanka", + 'SD' => "Sudan", + 'SR' => "Suriname", + 'SJ' => "Svalbard and Jan Mayen", + 'SZ' => "Swaziland", + 'SE' => "Sweden", + 'CH' => "Switzerland", + 'SY' => "Syrian Arab Republic", + 'TW' => "Taiwan", + 'TJ' => "Tajikistan", + 'TZ' => "Tanzania, United Republic of", + 'TH' => "Thailand", + 'TL' => "Timor-Leste", + 'TG' => "Togo", + 'TK' => "Tokelau", + 'TO' => "Tonga", + 'TT' => "Trinidad and Tobago", + 'TN' => "Tunisia", + 'TR' => "Turkey", + 'TM' => "Turkmenistan", + 'TC' => "Turks and Caicos Islands", + 'TV' => "Tuvalu", + 'UG' => "Uganda", + 'UA' => "Ukraine", + 'AE' => "United Arab Emirates", + 'GB' => "United Kingdom", + 'US' => "United States", + 'UM' => "United States Minor Outlying Islands", + 'UY' => "Uruguay", + 'UZ' => "Uzbekistan", + 'VU' => "Vanuatu", + 'VE' => "Venezuela", + 'VN' => "Vietnam", + 'VG' => "Virgin Islands, British", + 'VI' => "Virgin Islands, U.S.", + 'WF' => "Wallis and Futuna", + 'EH' => "Western Sahara", + 'YE' => "Yemen", + 'ZM' => "Zambia", + 'ZW' => "Zimbabwe", + ]; + + public $regions = [ + '-AU' => "Australia", + 'AU-ACT' => "Australia: Australian Capital Territory", + 'AU-NSW' => "Australia: New South Wales", + 'AU-NT' => "Australia: Northern Territory", + 'AU-QLD' => "Australia: Queensland", + 'AU-SA' => "Australia: South Australia", + 'AU-TAS' => "Australia: Tasmania", + 'AU-VIC' => "Australia: Victoria", + 'AU-WA' => "Australia: Western Australia", + + '--BE' => "", '-BE' => "Belgium", + 'BE-VAN' => "Belgium: Antwerpen", + 'BE-WBR' => "Belgium: Brabant Wallon", + 'BE-BRU' => "Belgium: Brussels-Capital Region", + 'BE-WHT' => "Belgium: Hainaut", + 'BE-WLG' => "Belgium: Liege", + 'BE-VLI' => "Belgium: Limburg", + 'BE-WLX' => "Belgium: Luxembourg, Luxemburg", + 'BE-WNA' => "Belgium: Namur", + 'BE-VOV' => "Belgium: Oost-Vlaanderen", + 'BE-VBR' => "Belgium: Vlaams-Brabant", + 'BE-VWV' => "Belgium: West-Vlaanderen", + + '--BR' => "", '-BR' => "Brazil", + 'BR-AC' => "Brazil: Acre", + 'BR-AL' => "Brazil: Alagoas", + 'BR-AP' => "Brazil: Amapá", + 'BR-AM' => "Brazil: Amazonas", + 'BR-BA' => "Brazil: Bahia", + 'BR-CE' => "Brazil: Ceará", + 'BR-DF' => "Brazil: Distrito Federal", + 'BR-ES' => "Brazil: Espírito Santo", + 'BR-FN' => "Brazil: Fernando de Noronha", + 'BR-GO' => "Brazil: Goiás", + 'BR-MA' => "Brazil: Maranhão", + 'BR-MT' => "Brazil: Mato Grosso", + 'BR-MS' => "Brazil: Mato Grosso do Sul", + 'BR-MG' => "Brazil: Minas Gerais", + 'BR-PR' => "Brazil: Paraná", + 'BR-PB' => "Brazil: Paraíba", + 'BR-PA' => "Brazil: Pará", + 'BR-PE' => "Brazil: Pernambuco", + 'BR-PI' => "Brazil: Piauí", + 'BR-RN' => "Brazil: Rio Grande do Norte", + 'BR-RS' => "Brazil: Rio Grande do Sul", + 'BR-RJ' => "Brazil: Rio de Janeiro", + 'BR-RO' => "Brazil: Rondônia", + 'BR-RR' => "Brazil: Roraima", + 'BR-SC' => "Brazil: Santa Catarina", + 'BR-SE' => "Brazil: Sergipe", + 'BR-SP' => "Brazil: São Paulo", + 'BR-TO' => "Brazil: Tocantins", + + '--BG' => "", '-BG' => "Bulgaria", + 'BG-01' => "Bulgaria: Blagoevgrad", + 'BG-02' => "Bulgaria: Burgas", + 'BG-08' => "Bulgaria: Dobrich", + 'BG-07' => "Bulgaria: Gabrovo", + 'BG-26' => "Bulgaria: Haskovo", + 'BG-09' => "Bulgaria: Kardzhali", + 'BG-10' => "Bulgaria: Kyustendil", + 'BG-11' => "Bulgaria: Lovech", + 'BG-12' => "Bulgaria: Montana", + 'BG-13' => "Bulgaria: Pazardzhik", + 'BG-14' => "Bulgaria: Pernik", + 'BG-15' => "Bulgaria: Pleven", + 'BG-16' => "Bulgaria: Plovdiv", + 'BG-17' => "Bulgaria: Razgrad", + 'BG-18' => "Bulgaria: Ruse", + 'BG-27' => "Bulgaria: Shumen", + 'BG-19' => "Bulgaria: Silistra", + 'BG-20' => "Bulgaria: Sliven", + 'BG-21' => "Bulgaria: Smolyan", + 'BG-23' => "Bulgaria: Sofia", + 'BG-22' => "Bulgaria: Sofia-Grad", + 'BG-24' => "Bulgaria: Stara Zagora", + 'BG-25' => "Bulgaria: Targovishte", + 'BG-03' => "Bulgaria: Varna", + 'BG-04' => "Bulgaria: Veliko Tarnovo", + 'BG-05' => "Bulgaria: Vidin", + 'BG-06' => "Bulgaria: Vratsa", + 'BG-28' => "Bulgaria: Yambol", + + '--CA' => "", '-CA' => "Canada", + 'CA-AB' => "Canada: Alberta", + 'CA-BC' => "Canada: British Columbia", + 'CA-MB' => "Canada: Manitoba", + 'CA-NB' => "Canada: New Brunswick", + 'CA-NL' => "Canada: Newfoundland and Labrador", + 'CA-NT' => "Canada: Northwest Territories", + 'CA-NS' => "Canada: Nova Scotia", + 'CA-NU' => "Canada: Nunavut", + 'CA-ON' => "Canada: Ontario", + 'CA-PE' => "Canada: Prince Edward Island", + 'CA-QC' => "Canada: Quebec", + 'CA-SK' => "Canada: Saskatchewan", + 'CA-YT' => "Canada: Yukon Territory", + + '--CN' => "", '-CN' => "China", + 'CN-34' => "China: Anhui", + 'CN-92' => "China: Aomen (Macau)", + 'CN-11' => "China: Beijing", + 'CN-50' => "China: Chongqing", + 'CN-35' => "China: Fujian", + 'CN-62' => "China: Gansu", + 'CN-44' => "China: Guangdong", + 'CN-45' => "China: Guangxi", + 'CN-52' => "China: Guizhou", + 'CN-46' => "China: Hainan", + 'CN-13' => "China: Hebei", + 'CN-23' => "China: Heilongjiang", + 'CN-41' => "China: Henan", + 'CN-42' => "China: Hubei", + 'CN-43' => "China: Hunan", + 'CN-32' => "China: Jiangsu", + 'CN-36' => "China: Jiangxi", + 'CN-22' => "China: Jilin", + 'CN-21' => "China: Liaoning", + 'CN-15' => "China: Nei Mongol", + 'CN-64' => "China: Ningxia", + 'CN-63' => "China: Qinghai", + 'CN-61' => "China: Shaanxi", + 'CN-37' => "China: Shandong", + 'CN-31' => "China: Shanghai", + 'CN-14' => "China: Shanxi", + 'CN-51' => "China: Sichuan", + 'CN-71' => "China: Taiwan", + 'CN-12' => "China: Tianjin", + 'CN-91' => "China: Xianggang (Hong-Kong)", + 'CN-65' => "China: Xinjiang", + 'CN-54' => "China: Xizang", + 'CN-53' => "China: Yunnan", + 'CN-33' => "China: Zhejiang", + + '--CY' => "", '-CY' => "Cyprus", + 'CY-04' => "Cyprus: Ammóchostos", + 'CY-06' => "Cyprus: Kerýneia", + 'CY-01' => "Cyprus: Lefkosía", + 'CY-02' => "Cyprus: Lemesós", + 'CY-03' => "Cyprus: Lárnaka", + 'CY-05' => "Cyprus: Páfos", + + '--CZ' => "", '-CZ' => "Czech Republic", + 'CZ-201' => "Czech Republic: Benešov", + 'CZ-202' => "Czech Republic: Beroun", + 'CZ-621' => "Czech Republic: Blansko", + 'CZ-622' => "Czech Republic: Brno-město", + 'CZ-623' => "Czech Republic: Brno-venkov", + 'CZ-801' => "Czech Republic: Bruntál", + 'CZ-624' => "Czech Republic: Břeclav", + 'CZ-411' => "Czech Republic: Cheb", + 'CZ-422' => "Czech Republic: Chomutov", + 'CZ-531' => "Czech Republic: Chrudim", + 'CZ-321' => "Czech Republic: Domažlice", + 'CZ-421' => "Czech Republic: Děčín", + 'CZ-802' => "Czech Republic: Frýdek Místek", + 'CZ-611' => "Czech Republic: Havlíčkův Brod", + 'CZ-625' => "Czech Republic: Hodonín", + 'CZ-521' => "Czech Republic: Hradec Králové", + 'CZ-512' => "Czech Republic: Jablonec nad Nisou", + 'CZ-711' => "Czech Republic: Jeseník", + 'CZ-612' => "Czech Republic: Jihlava", + 'CZ-JM' => "Czech Republic: Jihomoravský kraj", + 'CZ-JC' => "Czech Republic: Jihočeský kraj", + 'CZ-313' => "Czech Republic: Jindřichův Hradec", + 'CZ-522' => "Czech Republic: Jičín", + 'CZ-KA' => "Czech Republic: Karlovarský kraj", + 'CZ-412' => "Czech Republic: Karlovy Vary", + 'CZ-803' => "Czech Republic: Karviná", + 'CZ-203' => "Czech Republic: Kladno", + 'CZ-322' => "Czech Republic: Klatovy", + 'CZ-204' => "Czech Republic: Kolín", + 'CZ-721' => "Czech Republic: Kromĕříž", + 'CZ-KR' => "Czech Republic: Královéhradecký kraj", + 'CZ-205' => "Czech Republic: Kutná Hora", + 'CZ-513' => "Czech Republic: Liberec", + 'CZ-LI' => "Czech Republic: Liberecký kraj", + 'CZ-423' => "Czech Republic: Litoměřice", + 'CZ-424' => "Czech Republic: Louny", + 'CZ-207' => "Czech Republic: Mladá Boleslav", + 'CZ-MO' => "Czech Republic: Moravskoslezský kraj", + 'CZ-425' => "Czech Republic: Most", + 'CZ-206' => "Czech Republic: Mělník", + 'CZ-804' => "Czech Republic: Nový Jičín", + 'CZ-208' => "Czech Republic: Nymburk", + 'CZ-523' => "Czech Republic: Náchod", + 'CZ-712' => "Czech Republic: Olomouc", + 'CZ-OL' => "Czech Republic: Olomoucký kraj", + 'CZ-805' => "Czech Republic: Opava", + 'CZ-806' => "Czech Republic: Ostrava město", + 'CZ-532' => "Czech Republic: Pardubice", + 'CZ-PA' => "Czech Republic: Pardubický kraj", + 'CZ-613' => "Czech Republic: Pelhřimov", + 'CZ-324' => "Czech Republic: Plzeň jih", + 'CZ-323' => "Czech Republic: Plzeň město", + 'CZ-325' => "Czech Republic: Plzeň sever", + 'CZ-PL' => "Czech Republic: Plzeňský kraj", + 'CZ-315' => "Czech Republic: Prachatice", + 'CZ-101' => "Czech Republic: Praha 1", + 'CZ-10A' => "Czech Republic: Praha 10", + 'CZ-10B' => "Czech Republic: Praha 11", + 'CZ-10C' => "Czech Republic: Praha 12", + 'CZ-10D' => "Czech Republic: Praha 13", + 'CZ-10E' => "Czech Republic: Praha 14", + 'CZ-10F' => "Czech Republic: Praha 15", + 'CZ-102' => "Czech Republic: Praha 2", + 'CZ-103' => "Czech Republic: Praha 3", + 'CZ-104' => "Czech Republic: Praha 4", + 'CZ-105' => "Czech Republic: Praha 5", + 'CZ-106' => "Czech Republic: Praha 6", + 'CZ-107' => "Czech Republic: Praha 7", + 'CZ-108' => "Czech Republic: Praha 8", + 'CZ-109' => "Czech Republic: Praha 9", + 'CZ-209' => "Czech Republic: Praha východ", + 'CZ-20A' => "Czech Republic: Praha západ", + 'CZ-PR' => "Czech Republic: Praha, hlavní město", + 'CZ-713' => "Czech Republic: Prostĕjov", + 'CZ-314' => "Czech Republic: Písek", + 'CZ-714' => "Czech Republic: Přerov", + 'CZ-20B' => "Czech Republic: Příbram", + 'CZ-20C' => "Czech Republic: Rakovník", + 'CZ-326' => "Czech Republic: Rokycany", + 'CZ-524' => "Czech Republic: Rychnov nad Kněžnou", + 'CZ-514' => "Czech Republic: Semily", + 'CZ-413' => "Czech Republic: Sokolov", + 'CZ-316' => "Czech Republic: Strakonice", + 'CZ-ST' => "Czech Republic: Středočeský kraj", + 'CZ-533' => "Czech Republic: Svitavy", + 'CZ-327' => "Czech Republic: Tachov", + 'CZ-426' => "Czech Republic: Teplice", + 'CZ-525' => "Czech Republic: Trutnov", + 'CZ-317' => "Czech Republic: Tábor", + 'CZ-614' => "Czech Republic: Třebíč", + 'CZ-722' => "Czech Republic: Uherské Hradištĕ", + 'CZ-723' => "Czech Republic: Vsetín", + 'CZ-VY' => "Czech Republic: Vysočina", + 'CZ-626' => "Czech Republic: Vyškov", + 'CZ-724' => "Czech Republic: Zlín", + 'CZ-ZL' => "Czech Republic: Zlínský kraj", + 'CZ-627' => "Czech Republic: Znojmo", + 'CZ-US' => "Czech Republic: Ústecký kraj", + 'CZ-427' => "Czech Republic: Ústí nad Labem", + 'CZ-534' => "Czech Republic: Ústí nad Orlicí", + 'CZ-511' => "Czech Republic: Česká Lípa", + 'CZ-311' => "Czech Republic: České Budějovice", + 'CZ-312' => "Czech Republic: Český Krumlov", + 'CZ-715' => "Czech Republic: Šumperk", + 'CZ-615' => "Czech Republic: Žd’ár nad Sázavou", + + '--DK' => "", '-DK' => "Denmark", + 'DK-84' => "Denmark: Hovedstaden", + 'DK-82' => "Denmark: Midtjylland", + 'DK-81' => "Denmark: Nordjylland", + 'DK-85' => "Denmark: Sjælland", + 'DK-83' => "Denmark: Syddanmark", + + '--EG' => "", '-EG' => "Egypt", + 'EG-DK' => "Egypt: Ad Daqahlīyah", + 'EG-BA' => "Egypt: Al Bahr al Ahmar", + 'EG-BH' => "Egypt: Al Buhayrah", + 'EG-FYM' => "Egypt: Al Fayyūm", + 'EG-GH' => "Egypt: Al Gharbīyah", + 'EG-ALX' => "Egypt: Al Iskandarīyah", + 'EG-IS' => "Egypt: Al Ismā`īlīyah", + 'EG-GZ' => "Egypt: Al Jīzah", + 'EG-MN' => "Egypt: Al Minyā", + 'EG-MNF' => "Egypt: Al Minūfīyah", + 'EG-KB' => "Egypt: Al Qalyūbīyah", + 'EG-C' => "Egypt: Al Qāhirah", + 'EG-WAD' => "Egypt: Al Wādī al Jadīd", + 'EG-SUZ' => "Egypt: As Suways", + 'EG-SU' => "Egypt: As Sādis min Uktūbar", + 'EG-SHR' => "Egypt: Ash Sharqīyah", + 'EG-ASN' => "Egypt: Aswān", + 'EG-AST' => "Egypt: Asyūt", + 'EG-BNS' => "Egypt: Banī Suwayf", + 'EG-PTS' => "Egypt: Būr Sa`īd", + 'EG-DT' => "Egypt: Dumyāt", + 'EG-JS' => "Egypt: Janūb Sīnā'", + 'EG-KFS' => "Egypt: Kafr ash Shaykh", + 'EG-MT' => "Egypt: Matrūh", + 'EG-KN' => "Egypt: Qinā", + 'EG-SIN' => "Egypt: Shamal Sīnā'", + 'EG-SHG' => "Egypt: Sūhāj", + 'EG-HU' => "Egypt: Ḩulwān", + + '--FR' => "", '-FR' => "France", + 'FR-01' => "France: Ain", + 'FR-02' => "France: Aisne", + 'FR-03' => "France: Allier", + 'FR-06' => "France: Alpes-Maritimes", + 'FR-04' => "France: Alpes-de-Haute-Provence", + 'FR-A' => "France: Alsace", + 'FR-B' => "France: Aquitaine", + 'FR-08' => "France: Ardennes", + 'FR-07' => "France: Ardèche", + 'FR-09' => "France: Ariège", + 'FR-10' => "France: Aube", + 'FR-11' => "France: Aude", + 'FR-C' => "France: Auvergne", + 'FR-12' => "France: Aveyron", + 'FR-67' => "France: Bas-Rhin", + 'FR-P' => "France: Basse-Normandie", + 'FR-13' => "France: Bouches-du-Rhône", + 'FR-D' => "France: Bourgogne", + 'FR-E' => "France: Bretagne", + 'FR-14' => "France: Calvados", + 'FR-15' => "France: Cantal", + 'FR-F' => "France: Centre", + 'FR-G' => "France: Champagne-Ardenne", + 'FR-16' => "France: Charente", + 'FR-17' => "France: Charente-Maritime", + 'FR-18' => "France: Cher", + 'FR-CP' => "France: Clipperton", + 'FR-19' => "France: Corrèze", + 'FR-H' => "France: Corse", + 'FR-2A' => "France: Corse-du-Sud", + 'FR-23' => "France: Creuse", + 'FR-21' => "France: Côte-d'Or", + 'FR-22' => "France: Côtes-d'Armor", + 'FR-79' => "France: Deux-Sèvres", + 'FR-24' => "France: Dordogne", + 'FR-25' => "France: Doubs", + 'FR-26' => "France: Drôme", + 'FR-91' => "France: Essonne", + 'FR-27' => "France: Eure", + 'FR-28' => "France: Eure-et-Loir", + 'FR-29' => "France: Finistère", + 'FR-I' => "France: Franche-Comté", + 'FR-30' => "France: Gard", + 'FR-32' => "France: Gers", + 'FR-33' => "France: Gironde", + 'FR-GP' => "France: Guadeloupe", + 'FR-GF' => "France: Guyane", + 'FR-68' => "France: Haut-Rhin", + 'FR-2B' => "France: Haute-Corse", + 'FR-31' => "France: Haute-Garonne", + 'FR-43' => "France: Haute-Loire", + 'FR-52' => "France: Haute-Marne", + 'FR-Q' => "France: Haute-Normandie", + 'FR-74' => "France: Haute-Savoie", + 'FR-70' => "France: Haute-Saône", + 'FR-87' => "France: Haute-Vienne", + 'FR-05' => "France: Hautes-Alpes", + 'FR-65' => "France: Hautes-Pyrénées", + 'FR-92' => "France: Hauts-de-Seine", + 'FR-34' => "France: Hérault", + 'FR-35' => "France: Ille-et-Vilaine", + 'FR-36' => "France: Indre", + 'FR-37' => "France: Indre-et-Loire", + 'FR-38' => "France: Isère", + 'FR-39' => "France: Jura", + 'FR-40' => "France: Landes", + 'FR-K' => "France: Languedoc-Roussillon", + 'FR-L' => "France: Limousin", + 'FR-41' => "France: Loir-et-Cher", + 'FR-42' => "France: Loire", + 'FR-44' => "France: Loire-Atlantique", + 'FR-45' => "France: Loiret", + 'FR-M' => "France: Lorraine", + 'FR-46' => "France: Lot", + 'FR-47' => "France: Lot-et-Garonne", + 'FR-48' => "France: Lozère", + 'FR-49' => "France: Maine-et-Loire", + 'FR-50' => "France: Manche", + 'FR-51' => "France: Marne", + 'FR-MQ' => "France: Martinique", + 'FR-53' => "France: Mayenne", + 'FR-YT' => "France: Mayotte", + 'FR-54' => "France: Meurthe-et-Moselle", + 'FR-55' => "France: Meuse", + 'FR-N' => "France: Midi-Pyrénées", + 'FR-56' => "France: Morbihan", + 'FR-57' => "France: Moselle", + 'FR-58' => "France: Nièvre", + 'FR-59' => "France: Nord", + 'FR-O' => "France: Nord - Pas-de-Calais", + 'FR-NC' => "France: Nouvelle-Calédonie", + 'FR-60' => "France: Oise", + 'FR-61' => "France: Orne", + 'FR-75' => "France: Paris", + 'FR-62' => "France: Pas-de-Calais", + 'FR-R' => "France: Pays de la Loire", + 'FR-S' => "France: Picardie", + 'FR-T' => "France: Poitou-Charentes", + 'FR-PF' => "France: Polynésie française", + 'FR-U' => "France: Provence-Alpes-Côte d'Azur", + 'FR-63' => "France: Puy-de-Dôme", + 'FR-64' => "France: Pyrénées-Atlantiques", + 'FR-66' => "France: Pyrénées-Orientales", + 'FR-69' => "France: Rhône", + 'FR-V' => "France: Rhône-Alpes", + 'FR-RE' => "France: Réunion", + 'FR-BL' => "France: Saint-Barthélemy", + 'FR-MF' => "France: Saint-Martin", + 'FR-PM' => "France: Saint-Pierre-et-Miquelon", + 'FR-72' => "France: Sarthe", + 'FR-73' => "France: Savoie", + 'FR-71' => "France: Saône-et-Loire", + 'FR-76' => "France: Seine-Maritime", + 'FR-93' => "France: Seine-Saint-Denis", + 'FR-77' => "France: Seine-et-Marne", + 'FR-80' => "France: Somme", + 'FR-81' => "France: Tarn", + 'FR-82' => "France: Tarn-et-Garonne", + 'FR-TF' => "France: Terres australes françaises", + 'FR-90' => "France: Territoire de Belfort", + 'FR-95' => "France: Val d'Oise", + 'FR-94' => "France: Val-de-Marne", + 'FR-83' => "France: Var", + 'FR-84' => "France: Vaucluse", + 'FR-85' => "France: Vendée", + 'FR-86' => "France: Vienne", + 'FR-88' => "France: Vosges", + 'FR-WF' => "France: Wallis-et-Futuna", + 'FR-89' => "France: Yonne", + 'FR-78' => "France: Yvelines", + 'FR-J' => "France: Île-de-France", + + '--DE' => "", '-DE' => "Germany", + 'DE-BW' => "Germany: Baden-Württemberg", + 'DE-BY' => "Germany: Bayern", + 'DE-BE' => "Germany: Berlin", + 'DE-BB' => "Germany: Brandenburg", + 'DE-HB' => "Germany: Bremen", + 'DE-HH' => "Germany: Hamburg", + 'DE-HE' => "Germany: Hessen", + 'DE-MV' => "Germany: Mecklenburg-Vorpommern", + 'DE-NI' => "Germany: Niedersachsen", + 'DE-NW' => "Germany: Nordrhein-Westfalen", + 'DE-RP' => "Germany: Rheinland-Pfalz", + 'DE-SL' => "Germany: Saarland", + 'DE-SN' => "Germany: Sachsen", + 'DE-ST' => "Germany: Sachsen-Anhalt", + 'DE-SH' => "Germany: Schleswig-Holstein", + 'DE-TH' => "Germany: Thüringen", + + '--GR' => "", '-GR' => "Greece", + 'GR-13' => "Greece: Achaïa", + 'GR-69' => "Greece: Agio Oros", + 'GR-01' => "Greece: Aitolia kai Akarnania", + 'GR-A' => "Greece: Anatoliki Makedonia kai Thraki", + 'GR-11' => "Greece: Argolida", + 'GR-12' => "Greece: Arkadia", + 'GR-31' => "Greece: Arta", + 'GR-A1' => "Greece: Attiki", + 'GR-64' => "Greece: Chalkidiki", + 'GR-94' => "Greece: Chania", + 'GR-85' => "Greece: Chios", + 'GR-81' => "Greece: Dodekanisos", + 'GR-52' => "Greece: Drama", + 'GR-G' => "Greece: Dytiki Ellada", + 'GR-C' => "Greece: Dytiki Makedonia", + 'GR-71' => "Greece: Evros", + 'GR-05' => "Greece: Evrytania", + 'GR-04' => "Greece: Evvoias", + 'GR-63' => "Greece: Florina", + 'GR-07' => "Greece: Fokida", + 'GR-06' => "Greece: Fthiotida", + 'GR-51' => "Greece: Grevena", + 'GR-14' => "Greece: Ileia", + 'GR-53' => "Greece: Imathia", + 'GR-33' => "Greece: Ioannina", + 'GR-F' => "Greece: Ionia Nisia", + 'GR-D' => "Greece: Ipeiros", + 'GR-91' => "Greece: Irakleio", + 'GR-41' => "Greece: Karditsa", + 'GR-56' => "Greece: Kastoria", + 'GR-55' => "Greece: Kavala", + 'GR-23' => "Greece: Kefallonia", + 'GR-B' => "Greece: Kentriki Makedonia", + 'GR-22' => "Greece: Kerkyra", + 'GR-57' => "Greece: Kilkis", + 'GR-15' => "Greece: Korinthia", + 'GR-58' => "Greece: Kozani", + 'GR-M' => "Greece: Kriti", + 'GR-82' => "Greece: Kyklades", + 'GR-16' => "Greece: Lakonia", + 'GR-42' => "Greece: Larisa", + 'GR-92' => "Greece: Lasithi", + 'GR-24' => "Greece: Lefkada", + 'GR-83' => "Greece: Lesvos", + 'GR-43' => "Greece: Magnisia", + 'GR-17' => "Greece: Messinia", + 'GR-L' => "Greece: Notio Aigaio", + 'GR-59' => "Greece: Pella", + 'GR-J' => "Greece: Peloponnisos", + 'GR-61' => "Greece: Pieria", + 'GR-34' => "Greece: Preveza", + 'GR-93' => "Greece: Rethymno", + 'GR-73' => "Greece: Rodopi", + 'GR-84' => "Greece: Samos", + 'GR-62' => "Greece: Serres", + 'GR-H' => "Greece: Sterea Ellada", + 'GR-32' => "Greece: Thesprotia", + 'GR-E' => "Greece: Thessalia", + 'GR-54' => "Greece: Thessaloniki", + 'GR-44' => "Greece: Trikala", + 'GR-03' => "Greece: Voiotia", + 'GR-K' => "Greece: Voreio Aigaio", + 'GR-72' => "Greece: Xanthi", + 'GR-21' => "Greece: Zakynthos", + + '--HU' => "", '-HU' => "Hungary", + 'HU-BA' => "Hungary: Baranya", + 'HU-BZ' => "Hungary: Borsod-Abaúj-Zemplén", + 'HU-BU' => "Hungary: Budapest", + 'HU-BK' => "Hungary: Bács-Kiskun", + 'HU-BE' => "Hungary: Békés", + 'HU-BC' => "Hungary: Békéscsaba", + 'HU-CS' => "Hungary: Csongrád", + 'HU-DE' => "Hungary: Debrecen", + 'HU-DU' => "Hungary: Dunaújváros", + 'HU-EG' => "Hungary: Eger", + 'HU-FE' => "Hungary: Fejér", + 'HU-GY' => "Hungary: Győr", + 'HU-GS' => "Hungary: Győr-Moson-Sopron", + 'HU-HB' => "Hungary: Hajdú-Bihar", + 'HU-HE' => "Hungary: Heves", + 'HU-HV' => "Hungary: Hódmezővásárhely", + 'HU-JN' => "Hungary: Jász-Nagykun-Szolnok", + 'HU-KV' => "Hungary: Kaposvár", + 'HU-KM' => "Hungary: Kecskemét", + 'HU-KE' => "Hungary: Komárom-Esztergom", + 'HU-MI' => "Hungary: Miskolc", + 'HU-NK' => "Hungary: Nagykanizsa", + 'HU-NY' => "Hungary: Nyíregyháza", + 'HU-NO' => "Hungary: Nógrád", + 'HU-PE' => "Hungary: Pest", + 'HU-PS' => "Hungary: Pécs", + 'HU-ST' => "Hungary: Salgótarján", + 'HU-SO' => "Hungary: Somogy", + 'HU-SN' => "Hungary: Sopron", + 'HU-SZ' => "Hungary: Szabolcs-Szatmár-Bereg", + 'HU-SD' => "Hungary: Szeged", + 'HU-SS' => "Hungary: Szekszárd", + 'HU-SK' => "Hungary: Szolnok", + 'HU-SH' => "Hungary: Szombathely", + 'HU-SF' => "Hungary: Székesfehérvár", + 'HU-TB' => "Hungary: Tatabánya", + 'HU-TO' => "Hungary: Tolna", + 'HU-VA' => "Hungary: Vas", + 'HU-VM' => "Hungary: Veszprém", + 'HU-VE' => "Hungary: Veszprém (county)", + 'HU-ZA' => "Hungary: Zala", + 'HU-ZE' => "Hungary: Zalaegerszeg", + 'HU-ER' => "Hungary: Érd", + + '--IS' => "", '-IS' => "Iceland", + 'IS-7' => "Iceland: Austurland", + 'IS-1' => "Iceland: Höfuðborgarsvæðið", + 'IS-6' => "Iceland: Norðurland eystra", + 'IS-5' => "Iceland: Norðurland vestra", + 'IS-0' => "Iceland: Reykjavík", + 'IS-8' => "Iceland: Suðurland", + 'IS-2' => "Iceland: Suðurnes", + 'IS-4' => "Iceland: Vestfirðir", + 'IS-3' => "Iceland: Vesturland", + + '--IN' => "", '-IN' => "India", + 'IN-AN' => "India: Andaman and Nicobar Islands", + 'IN-AP' => "India: Andhra Pradesh", + 'IN-AR' => "India: Arunāchal Pradesh", + 'IN-AS' => "India: Assam", + 'IN-BR' => "India: Bihār", + 'IN-CH' => "India: Chandīgarh", + 'IN-CT' => "India: Chhattīsgarh", + 'IN-DD' => "India: Damān and Diu", + 'IN-DL' => "India: Delhi", + 'IN-DN' => "India: Dādra and Nagar Haveli", + 'IN-GA' => "India: Goa", + 'IN-GJ' => "India: Gujarāt", + 'IN-HR' => "India: Haryāna", + 'IN-HP' => "India: Himāchal Pradesh", + 'IN-JK' => "India: Jammu and Kashmīr", + 'IN-JH' => "India: Jharkhand", + 'IN-KA' => "India: Karnātaka", + 'IN-KL' => "India: Kerala", + 'IN-LD' => "India: Lakshadweep", + 'IN-MP' => "India: Madhya Pradesh", + 'IN-MH' => "India: Mahārāshtra", + 'IN-MN' => "India: Manipur", + 'IN-ML' => "India: Meghālaya", + 'IN-MZ' => "India: Mizoram", + 'IN-NL' => "India: Nāgāland", + 'IN-OR' => "India: Orissa", + 'IN-PY' => "India: Pondicherry", + 'IN-PB' => "India: Punjab", + 'IN-RJ' => "India: Rājasthān", + 'IN-SK' => "India: Sikkim", + 'IN-TN' => "India: Tamil Nādu", + 'IN-TR' => "India: Tripura", + 'IN-UP' => "India: Uttar Pradesh", + 'IN-UL' => "India: Uttaranchal", + 'IN-WB' => "India: West Bengal", + + '--ID' => "", '-ID' => "Indonesia", + 'ID-AC' => "Indonesia: Aceh", + 'ID-BA' => "Indonesia: Bali", + 'ID-BB' => "Indonesia: Bangka Belitung", + 'ID-BT' => "Indonesia: Banten", + 'ID-BE' => "Indonesia: Bengkulu", + 'ID-GO' => "Indonesia: Gorontalo", + 'ID-JK' => "Indonesia: Jakarta Raya", + 'ID-JA' => "Indonesia: Jambi", + 'ID-JW' => "Indonesia: Jawa", + 'ID-JB' => "Indonesia: Jawa Barat", + 'ID-JT' => "Indonesia: Jawa Tengah", + 'ID-JI' => "Indonesia: Jawa Timur", + 'ID-KA' => "Indonesia: Kalimantan", + 'ID-KB' => "Indonesia: Kalimantan Barat", + 'ID-KS' => "Indonesia: Kalimantan Selatan", + 'ID-KT' => "Indonesia: Kalimantan Tengah", + 'ID-KI' => "Indonesia: Kalimantan Timur", + 'ID-KR' => "Indonesia: Kepulauan Riau", + 'ID-LA' => "Indonesia: Lampung", + 'ID-MA' => "Indonesia: Maluku", + 'ID-MU' => "Indonesia: Maluku Utara", + 'ID-NU' => "Indonesia: Nusa Tenggara", + 'ID-NB' => "Indonesia: Nusa Tenggara Barat", + 'ID-NT' => "Indonesia: Nusa Tenggara Timur", + 'ID-PA' => "Indonesia: Papua", + 'ID-PB' => "Indonesia: Papua Barat", + 'ID-RI' => "Indonesia: Riau", + 'ID-SL' => "Indonesia: Sulawesi", + 'ID-SR' => "Indonesia: Sulawesi Barat", + 'ID-SN' => "Indonesia: Sulawesi Selatan", + 'ID-ST' => "Indonesia: Sulawesi Tengah", + 'ID-SG' => "Indonesia: Sulawesi Tenggara", + 'ID-SA' => "Indonesia: Sulawesi Utara", + 'ID-SM' => "Indonesia: Sumatera", + 'ID-SU' => "Indonesia: Sumatera Utara", + 'ID-SB' => "Indonesia: Sumatra Barat", + 'ID-SS' => "Indonesia: Sumatra Selatan", + 'ID-YO' => "Indonesia: Yogyakarta", + + '--IE' => "", '-IE' => "Ireland", + 'IE-CW' => "Ireland: Carlow", + 'IE-CN' => "Ireland: Cavan", + 'IE-CE' => "Ireland: Clare", + 'IE-C' => "Ireland: Connacht", + 'IE-C' => "Ireland: Cork", + 'IE-DL' => "Ireland: Donegal", + 'IE-D' => "Ireland: Dublin", + 'IE-G' => "Ireland: Galway", + 'IE-KY' => "Ireland: Kerry", + 'IE-KE' => "Ireland: Kildare", + 'IE-KK' => "Ireland: Kilkenny", + 'IE-LS' => "Ireland: Laois", + 'IE-L' => "Ireland: Leinster", + 'IE-LM' => "Ireland: Leitrim", + 'IE-LK' => "Ireland: Limerick", + 'IE-LD' => "Ireland: Longford", + 'IE-LH' => "Ireland: Louth", + 'IE-MO' => "Ireland: Mayo", + 'IE-MH' => "Ireland: Meath", + 'IE-MN' => "Ireland: Monaghan", + 'IE-M' => "Ireland: Munster", + 'IE-OY' => "Ireland: Offaly", + 'IE-RN' => "Ireland: Roscommon", + 'IE-SO' => "Ireland: Sligo", + 'IE-TA' => "Ireland: Tipperary", + 'IE-U' => "Ireland: Ulster", + 'IE-WD' => "Ireland: Waterford", + 'IE-WH' => "Ireland: Westmeath", + 'IE-WX' => "Ireland: Wexford", + 'IE-WW' => "Ireland: Wicklow", + + '--IL' => "", '-IL' => "Israel", + 'IL-D' => "Israel: HaDarom", + 'IL-M' => "Israel: HaMerkaz", + 'IL-Z' => "Israel: HaZafon", + 'IL-HA' => "Israel: Hefa", + 'IL-TA' => "Israel: Tel-Aviv", + 'IL-JM' => "Israel: Yerushalayim Al Quds", + + '--IT' => "", '-IT' => "Italy", + 'IT-65' => "Italy: Abruzzo", + 'IT-AG' => "Italy: Agrigento", + 'IT-AL' => "Italy: Alessandria", + 'IT-AN' => "Italy: Ancona", + 'IT-AO' => "Italy: Aosta", + 'IT-AR' => "Italy: Arezzo", + 'IT-AP' => "Italy: Ascoli Piceno", + 'IT-AT' => "Italy: Asti", + 'IT-AV' => "Italy: Avellino", + 'IT-BA' => "Italy: Bari", + 'IT-BT' => "Italy: Barletta-Andria-Trani", + 'IT-77' => "Italy: Basilicata", + 'IT-BL' => "Italy: Belluno", + 'IT-BN' => "Italy: Benevento", + 'IT-BG' => "Italy: Bergamo", + 'IT-BI' => "Italy: Biella", + 'IT-BO' => "Italy: Bologna", + 'IT-BZ' => "Italy: Bolzano", + 'IT-BS' => "Italy: Brescia", + 'IT-BR' => "Italy: Brindisi", + 'IT-CA' => "Italy: Cagliari", + 'IT-78' => "Italy: Calabria", + 'IT-CL' => "Italy: Caltanissetta", + 'IT-72' => "Italy: Campania", + 'IT-CB' => "Italy: Campobasso", + 'IT-CI' => "Italy: Carbonia-Iglesias", + 'IT-CE' => "Italy: Caserta", + 'IT-CT' => "Italy: Catania", + 'IT-CZ' => "Italy: Catanzaro", + 'IT-CH' => "Italy: Chieti", + 'IT-CO' => "Italy: Como", + 'IT-CS' => "Italy: Cosenza", + 'IT-CR' => "Italy: Cremona", + 'IT-KR' => "Italy: Crotone", + 'IT-CN' => "Italy: Cuneo", + 'IT-45' => "Italy: Emilia-Romagna", + 'IT-EN' => "Italy: Enna", + 'IT-FM' => "Italy: Fermo", + 'IT-FE' => "Italy: Ferrara", + 'IT-FI' => "Italy: Firenze", + 'IT-FG' => "Italy: Foggia", + 'IT-FC' => "Italy: Forlì-Cesena", + 'IT-36' => "Italy: Friuli-Venezia Giulia", + 'IT-FR' => "Italy: Frosinone", + 'IT-GE' => "Italy: Genova", + 'IT-GO' => "Italy: Gorizia", + 'IT-GR' => "Italy: Grosseto", + 'IT-IM' => "Italy: Imperia", + 'IT-IS' => "Italy: Isernia", + 'IT-AQ' => "Italy: L'Aquila", + 'IT-SP' => "Italy: La Spezia", + 'IT-LT' => "Italy: Latina", + 'IT-62' => "Italy: Lazio", + 'IT-LE' => "Italy: Lecce", + 'IT-LC' => "Italy: Lecco", + 'IT-42' => "Italy: Liguria", + 'IT-LI' => "Italy: Livorno", + 'IT-LO' => "Italy: Lodi", + 'IT-25' => "Italy: Lombardia", + 'IT-LU' => "Italy: Lucca", + 'IT-MC' => "Italy: Macerata", + 'IT-MN' => "Italy: Mantova", + 'IT-57' => "Italy: Marche", + 'IT-MS' => "Italy: Massa-Carrara", + 'IT-MT' => "Italy: Matera", + 'IT-VS' => "Italy: Medio Campidano", + 'IT-ME' => "Italy: Messina", + 'IT-MI' => "Italy: Milano", + 'IT-MO' => "Italy: Modena", + 'IT-67' => "Italy: Molise", + 'IT-MB' => "Italy: Monza e Brianza", + 'IT-NA' => "Italy: Napoli", + 'IT-NO' => "Italy: Novara", + 'IT-NU' => "Italy: Nuoro", + 'IT-OG' => "Italy: Ogliastra", + 'IT-OT' => "Italy: Olbia-Tempio", + 'IT-OR' => "Italy: Oristano", + 'IT-PD' => "Italy: Padova", + 'IT-PA' => "Italy: Palermo", + 'IT-PR' => "Italy: Parma", + 'IT-PV' => "Italy: Pavia", + 'IT-PG' => "Italy: Perugia", + 'IT-PU' => "Italy: Pesaro e Urbino", + 'IT-PE' => "Italy: Pescara", + 'IT-PC' => "Italy: Piacenza", + 'IT-21' => "Italy: Piemonte", + 'IT-PI' => "Italy: Pisa", + 'IT-PT' => "Italy: Pistoia", + 'IT-PN' => "Italy: Pordenone", + 'IT-PZ' => "Italy: Potenza", + 'IT-PO' => "Italy: Prato", + 'IT-75' => "Italy: Puglia", + 'IT-RG' => "Italy: Ragusa", + 'IT-RA' => "Italy: Ravenna", + 'IT-RC' => "Italy: Reggio Calabria", + 'IT-RE' => "Italy: Reggio Emilia", + 'IT-RI' => "Italy: Rieti", + 'IT-RN' => "Italy: Rimini", + 'IT-RM' => "Italy: Roma", + 'IT-RO' => "Italy: Rovigo", + 'IT-SA' => "Italy: Salerno", + 'IT-88' => "Italy: Sardegna", + 'IT-SS' => "Italy: Sassari", + 'IT-SV' => "Italy: Savona", + 'IT-82' => "Italy: Sicilia", + 'IT-SI' => "Italy: Siena", + 'IT-SR' => "Italy: Siracusa", + 'IT-SO' => "Italy: Sondrio", + 'IT-TA' => "Italy: Taranto", + 'IT-TE' => "Italy: Teramo", + 'IT-TR' => "Italy: Terni", + 'IT-TO' => "Italy: Torino", + 'IT-52' => "Italy: Toscana", + 'IT-TP' => "Italy: Trapani", + 'IT-32' => "Italy: Trentino-Alto Adige", + 'IT-TN' => "Italy: Trento", + 'IT-TV' => "Italy: Treviso", + 'IT-TS' => "Italy: Trieste", + 'IT-UD' => "Italy: Udine", + 'IT-55' => "Italy: Umbria", + 'IT-23' => "Italy: Valle d'Aosta", + 'IT-VA' => "Italy: Varese", + 'IT-34' => "Italy: Veneto", + 'IT-VE' => "Italy: Venezia", + 'IT-VB' => "Italy: Verbano-Cusio-Ossola", + 'IT-VC' => "Italy: Vercelli", + 'IT-VR' => "Italy: Verona", + 'IT-VV' => "Italy: Vibo Valentia", + 'IT-VI' => "Italy: Vicenza", + 'IT-VT' => "Italy: Viterbo", + + '--JP' => "", '-JP' => "Japan", + 'JP-23' => "Japan: Aichi", + 'JP-05' => "Japan: Akita", + 'JP-02' => "Japan: Aomori", + 'JP-12' => "Japan: Chiba", + 'JP-38' => "Japan: Ehime", + 'JP-18' => "Japan: Fukui", + 'JP-40' => "Japan: Fukuoka", + 'JP-07' => "Japan: Fukushima", + 'JP-21' => "Japan: Gifu", + 'JP-10' => "Japan: Gunma", + 'JP-34' => "Japan: Hiroshima", + 'JP-01' => "Japan: Hokkaido", + 'JP-28' => "Japan: Hyogo", + 'JP-08' => "Japan: Ibaraki", + 'JP-17' => "Japan: Ishikawa", + 'JP-03' => "Japan: Iwate", + 'JP-37' => "Japan: Kagawa", + 'JP-46' => "Japan: Kagoshima", + 'JP-14' => "Japan: Kanagawa", + 'JP-39' => "Japan: Kochi", + 'JP-43' => "Japan: Kumamoto", + 'JP-26' => "Japan: Kyoto", + 'JP-24' => "Japan: Mie", + 'JP-04' => "Japan: Miyagi", + 'JP-45' => "Japan: Miyazaki", + 'JP-20' => "Japan: Nagano", + 'JP-42' => "Japan: Nagasaki", + 'JP-29' => "Japan: Nara", + 'JP-15' => "Japan: Niigata", + 'JP-44' => "Japan: Oita", + 'JP-33' => "Japan: Okayama", + 'JP-47' => "Japan: Okinawa", + 'JP-27' => "Japan: Osaka", + 'JP-41' => "Japan: Saga", + 'JP-11' => "Japan: Saitama", + 'JP-25' => "Japan: Shiga", + 'JP-32' => "Japan: Shimane", + 'JP-22' => "Japan: Shizuoka", + 'JP-09' => "Japan: Tochigi", + 'JP-36' => "Japan: Tokushima", + 'JP-13' => "Japan: Tokyo", + 'JP-31' => "Japan: Tottori", + 'JP-16' => "Japan: Toyama", + 'JP-30' => "Japan: Wakayama", + 'JP-06' => "Japan: Yamagata", + 'JP-35' => "Japan: Yamaguchi", + 'JP-19' => "Japan: Yamanashi", + + '--MX' => "", '-MX' => "Mexico", + 'MX-AGU' => "Mexico: Aguascalientes", + 'MX-BCN' => "Mexico: Baja California", + 'MX-BCS' => "Mexico: Baja California Sur", + 'MX-CAM' => "Mexico: Campeche", + 'MX-CHP' => "Mexico: Chiapas", + 'MX-CHH' => "Mexico: Chihuahua", + 'MX-COA' => "Mexico: Coahuila", + 'MX-COL' => "Mexico: Colima", + 'MX-DIF' => "Mexico: Distrito Federal (Mexico City)", + 'MX-DUR' => "Mexico: Durango", + 'MX-GUA' => "Mexico: Guanajuato", + 'MX-GRO' => "Mexico: Guerrero", + 'MX-HID' => "Mexico: Hidalgo", + 'MX-JAL' => "Mexico: Jalisco", + 'MX-MIC' => "Mexico: Michoacán", + 'MX-MOR' => "Mexico: Morelos", + 'MX-MEX' => "Mexico: México", + 'MX-NAY' => "Mexico: Nayarit", + 'MX-NLE' => "Mexico: Nuevo León", + 'MX-OAX' => "Mexico: Oaxaca", + 'MX-PUE' => "Mexico: Puebla", + 'MX-QUE' => "Mexico: Querétaro", + 'MX-ROO' => "Mexico: Quintana Roo", + 'MX-SLP' => "Mexico: San Luis Potosí", + 'MX-SIN' => "Mexico: Sinaloa", + 'MX-SON' => "Mexico: Sonora", + 'MX-TAB' => "Mexico: Tabasco", + 'MX-TAM' => "Mexico: Tamaulipas", + 'MX-TLA' => "Mexico: Tlaxcala", + 'MX-VER' => "Mexico: Veracruz", + 'MX-YUC' => "Mexico: Yucatán", + 'MX-ZAC' => "Mexico: Zacatecas", + + '--MA' => "", '-MA' => "Morocco", + 'MA-AGD' => "Morocco: Agadir-Ida-Outanane", + 'MA-HAO' => "Morocco: Al Haouz", + 'MA-HOC' => "Morocco: Al Hoceïma", + 'MA-AOU' => "Morocco: Aousserd", + 'MA-ASZ' => "Morocco: Assa-Zag", + 'MA-AZI' => "Morocco: Azilal", + 'MA-BES' => "Morocco: Ben Slimane", + 'MA-BEM' => "Morocco: Beni Mellal", + 'MA-BER' => "Morocco: Berkane", + 'MA-BOD' => "Morocco: Boujdour (EH)", + 'MA-BOM' => "Morocco: Boulemane", + 'MA-CAS' => "Morocco: Casablanca [Dar el Beïda]", + 'MA-09' => "Morocco: Chaouia-Ouardigha", + 'MA-CHE' => "Morocco: Chefchaouen", + 'MA-CHI' => "Morocco: Chichaoua", + 'MA-CHT' => "Morocco: Chtouka-Ait Baha", + 'MA-10' => "Morocco: Doukhala-Abda", + 'MA-HAJ' => "Morocco: El Hajeb", + 'MA-JDI' => "Morocco: El Jadida", + 'MA-ERR' => "Morocco: Errachidia", + 'MA-ESM' => "Morocco: Es Smara (EH)", + 'MA-ESI' => "Morocco: Essaouira", + 'MA-FAH' => "Morocco: Fahs-Beni Makada", + 'MA-FIG' => "Morocco: Figuig", + 'MA-05' => "Morocco: Fès-Boulemane", + 'MA-FES' => "Morocco: Fès-Dar-Dbibegh", + 'MA-02' => "Morocco: Gharb-Chrarda-Beni Hssen", + 'MA-08' => "Morocco: Grand Casablanca", + 'MA-GUE' => "Morocco: Guelmim", + 'MA-14' => "Morocco: Guelmim-Es Smara", + 'MA-IFR' => "Morocco: Ifrane", + 'MA-INE' => "Morocco: Inezgane-Ait Melloul", + 'MA-JRA' => "Morocco: Jrada", + 'MA-KES' => "Morocco: Kelaat es Sraghna", + 'MA-KHE' => "Morocco: Khemisaet", + 'MA-KHN' => "Morocco: Khenifra", + 'MA-KHO' => "Morocco: Khouribga", + 'MA-KEN' => "Morocco: Kénitra", + 'MA-04' => "Morocco: L'Oriental", + 'MA-LAR' => "Morocco: Larache", + 'MA-LAA' => "Morocco: Laâyoune (EH)", + 'MA-15' => "Morocco: Laâyoune-Boujdour-Sakia el Hamra", + 'MA-MMD' => "Morocco: Marrakech-Medina", + 'MA-MMN' => "Morocco: Marrakech-Menara", + 'MA-11' => "Morocco: Marrakech-Tensift-Al Haouz", + 'MA-MEK' => "Morocco: Meknès", + 'MA-06' => "Morocco: Meknès-Tafilalet", + 'MA-MOH' => "Morocco: Mohammadia", + 'MA-MOU' => "Morocco: Moulay Yacoub", + 'MA-MED' => "Morocco: Médiouna", + 'MA-NAD' => "Morocco: Nador", + 'MA-NOU' => "Morocco: Nouaceur", + 'MA-OUA' => "Morocco: Ouarzazate", + 'MA-OUD' => "Morocco: Oued ed Dahab (EH)", + 'MA-16' => "Morocco: Oued ed Dahab-Lagouira", + 'MA-OUJ' => "Morocco: Oujda-Angad", + 'MA-RAB' => "Morocco: Rabat", + 'MA-07' => "Morocco: Rabat-Salé-Zemmour-Zaer", + 'MA-SAF' => "Morocco: Safi", + 'MA-SAL' => "Morocco: Salé", + 'MA-SEF' => "Morocco: Sefrou", + 'MA-SET' => "Morocco: Settat", + 'MA-SYB' => "Morocco: Sidi Youssef Ben Ali", + 'MA-SIK' => "Morocco: Sidl Kacem", + 'MA-SKH' => "Morocco: Skhirate-Témara", + 'MA-13' => "Morocco: Sous-Massa-Draa", + 'MA-12' => "Morocco: Tadla-Azilal", + 'MA-TNT' => "Morocco: Tan-Tan", + 'MA-TNG' => "Morocco: Tanger-Assilah", + 'MA-01' => "Morocco: Tanger-Tétouan", + 'MA-TAO' => "Morocco: Taounate", + 'MA-TAI' => "Morocco: Taourirt", + 'MA-TAR' => "Morocco: Taroudant", + 'MA-TAT' => "Morocco: Tata", + 'MA-TAZ' => "Morocco: Taza", + 'MA-03' => "Morocco: Taza-Al Hoceima-Taounate", + 'MA-TIZ' => "Morocco: Tiznit", + 'MA-TET' => "Morocco: Tétouan", + 'MA-ZAG' => "Morocco: Zagora", + + '--NL' => "", '-NL' => "Netherlands", + 'NL-DR' => "Netherlands: Drenthe", + 'NL-FL' => "Netherlands: Flevoland", + 'NL-FR' => "Netherlands: Friesland", + 'NL-GE' => "Netherlands: Gelderland", + 'NL-GR' => "Netherlands: Groningen", + 'NL-LI' => "Netherlands: Limburg", + 'NL-NB' => "Netherlands: Noord-Brabant", + 'NL-NH' => "Netherlands: Noord-Holland", + 'NL-OV' => "Netherlands: Overijssel", + 'NL-UT' => "Netherlands: Utrecht", + 'NL-ZE' => "Netherlands: Zeeland", + 'NL-ZH' => "Netherlands: Zuid-Holland", + + '--NG' => "", '-NG' => "Nigeria", + 'NG-AB' => "Nigeria: Abia", + 'NG-FC' => "Nigeria: Abuja Capital Territory", + 'NG-AD' => "Nigeria: Adamawa", + 'NG-AK' => "Nigeria: Akwa Ibom", + 'NG-AN' => "Nigeria: Anambra", + 'NG-BA' => "Nigeria: Bauchi", + 'NG-BY' => "Nigeria: Bayelsa", + 'NG-BE' => "Nigeria: Benue", + 'NG-BO' => "Nigeria: Borno", + 'NG-CR' => "Nigeria: Cross River", + 'NG-DE' => "Nigeria: Delta", + 'NG-EB' => "Nigeria: Ebonyi", + 'NG-ED' => "Nigeria: Edo", + 'NG-EK' => "Nigeria: Ekiti", + 'NG-EN' => "Nigeria: Enugu", + 'NG-GO' => "Nigeria: Gombe", + 'NG-IM' => "Nigeria: Imo", + 'NG-JI' => "Nigeria: Jigawa", + 'NG-KD' => "Nigeria: Kaduna", + 'NG-KN' => "Nigeria: Kano", + 'NG-KT' => "Nigeria: Katsina", + 'NG-KE' => "Nigeria: Kebbi", + 'NG-KO' => "Nigeria: Kogi", + 'NG-KW' => "Nigeria: Kwara", + 'NG-LA' => "Nigeria: Lagos", + 'NG-NA' => "Nigeria: Nassarawa", + 'NG-NI' => "Nigeria: Niger, Níger", + 'NG-OG' => "Nigeria: Ogun", + 'NG-ON' => "Nigeria: Ondo", + 'NG-OS' => "Nigeria: Osun", + 'NG-OY' => "Nigeria: Oyo", + 'NG-PL' => "Nigeria: Plateau", + 'NG-RI' => "Nigeria: Rivers", + 'NG-SO' => "Nigeria: Sokoto", + 'NG-TA' => "Nigeria: Taraba", + 'NG-YO' => "Nigeria: Yobe", + 'NG-ZA' => "Nigeria: Zamfara", + + '--NO' => "", '-NO' => "Norway", + 'NO-02' => "Norway: Akershus", + 'NO-09' => "Norway: Aust-Agder", + 'NO-06' => "Norway: Buskerud", + 'NO-20' => "Norway: Finnmark", + 'NO-04' => "Norway: Hedmark", + 'NO-12' => "Norway: Hordaland", + 'NO-22' => "Norway: Jan Mayen", + 'NO-15' => "Norway: Møre og Romsdal", + 'NO-17' => "Norway: Nord-Trøndelag", + 'NO-18' => "Norway: Nordland", + 'NO-05' => "Norway: Oppland", + 'NO-03' => "Norway: Oslo", + 'NO-11' => "Norway: Rogaland", + 'NO-14' => "Norway: Sogn og Fjordane", + 'NO-21' => "Norway: Svalbard", + 'NO-16' => "Norway: Sør-Trøndelag", + 'NO-08' => "Norway: Telemark", + 'NO-19' => "Norway: Troms", + 'NO-10' => "Norway: Vest-Agder", + 'NO-07' => "Norway: Vestfold", + 'NO-01' => "Norway: Østfold", + + '--PH' => "", '-PH' => "Philippines", + 'PH-ABR' => "Philippines: Abra", + 'PH-AGN' => "Philippines: Agusan del Norte", + 'PH-AGS' => "Philippines: Agusan del Sur", + 'PH-AKL' => "Philippines: Aklan", + 'PH-ALB' => "Philippines: Albay", + 'PH-ANT' => "Philippines: Antique", + 'PH-APA' => "Philippines: Apayao", + 'PH-AUR' => "Philippines: Aurora", + 'PH-14' => "Philippines: Autonomous Region in Muslim Mindanao (ARMM)", + 'PH-BAS' => "Philippines: Basilan", + 'PH-BTN' => "Philippines: Batanes", + 'PH-BTG' => "Philippines: Batangas", + 'PH-BAN' => "Philippines: Batasn", + 'PH-BEN' => "Philippines: Benguet", + 'PH-05' => "Philippines: Bicol (Region V)", + 'PH-BIL' => "Philippines: Biliran", + 'PH-BOH' => "Philippines: Bohol", + 'PH-BUK' => "Philippines: Bukidnon", + 'PH-BUL' => "Philippines: Bulacan", + 'PH-40' => "Philippines: CALABARZON (Region IV-A)", + 'PH-CAG' => "Philippines: Cagayan", + 'PH-02' => "Philippines: Cagayan Valley (Region II)", + 'PH-CAN' => "Philippines: Camarines Norte", + 'PH-CAS' => "Philippines: Camarines Sur", + 'PH-CAM' => "Philippines: Camiguin", + 'PH-CAP' => "Philippines: Capiz", + 'PH-13' => "Philippines: Caraga (Region XIII)", + 'PH-CAT' => "Philippines: Catanduanes", + 'PH-CAV' => "Philippines: Cavite", + 'PH-CEB' => "Philippines: Cebu", + 'PH-03' => "Philippines: Central Luzon (Region III)", + 'PH-07' => "Philippines: Central Visayas (Region VII)", + 'PH-COM' => "Philippines: Compostela Valley", + 'PH-15' => "Philippines: Cordillera Administrative Region (CAR)", + 'PH-11' => "Philippines: Davao (Region XI)", + 'PH-DAO' => "Philippines: Davao Oriental", + 'PH-DAV' => "Philippines: Davao del Norte", + 'PH-DAS' => "Philippines: Davao del Sur", + 'PH-DIN' => "Philippines: Dinagat Islands", + 'PH-EAS' => "Philippines: Eastern Samar", + 'PH-08' => "Philippines: Eastern Visayas (Region VIII)", + 'PH-GUI' => "Philippines: Guimaras", + 'PH-IFU' => "Philippines: Ifugao", + 'PH-01' => "Philippines: Ilocos (Region I)", + 'PH-ILN' => "Philippines: Ilocos Norte", + 'PH-ILS' => "Philippines: Ilocos Sur", + 'PH-ILI' => "Philippines: Iloilo", + 'PH-ISA' => "Philippines: Isabela", + 'PH-KAL' => "Philippines: Kalinga-Apayso", + 'PH-LUN' => "Philippines: La Union", + 'PH-LAG' => "Philippines: Laguna", + 'PH-LAN' => "Philippines: Lanao del Norte", + 'PH-LAS' => "Philippines: Lanao del Sur", + 'PH-LEY' => "Philippines: Leyte", + 'PH-41' => "Philippines: MIMAROPA (Region IV-B)", + 'PH-MAG' => "Philippines: Maguindanao", + 'PH-MAD' => "Philippines: Marinduque", + 'PH-MAS' => "Philippines: Masbate", + 'PH-MDC' => "Philippines: Mindoro Occidental", + 'PH-MDR' => "Philippines: Mindoro Oriental", + 'PH-MSC' => "Philippines: Misamis Occidental", + 'PH-MSR' => "Philippines: Misamis Oriental", + 'PH-MOU' => "Philippines: Mountain Province", + 'PH-00' => "Philippines: National Capital Region", + 'PH-NEC' => "Philippines: Negroe Occidental", + 'PH-NER' => "Philippines: Negros Oriental", + 'PH-NCO' => "Philippines: North Cotabato", + 'PH-10' => "Philippines: Northern Mindanao (Region X)", + 'PH-NSA' => "Philippines: Northern Samar", + 'PH-NUE' => "Philippines: Nueva Ecija", + 'PH-NUV' => "Philippines: Nueva Vizcaya", + 'PH-PLW' => "Philippines: Palawan", + 'PH-PAM' => "Philippines: Pampanga", + 'PH-PAN' => "Philippines: Pangasinan", + 'PH-QUE' => "Philippines: Quezon", + 'PH-QUI' => "Philippines: Quirino", + 'PH-RIZ' => "Philippines: Rizal", + 'PH-ROM' => "Philippines: Romblon", + 'PH-SAR' => "Philippines: Sarangani", + 'PH-SIG' => "Philippines: Siquijor", + 'PH-12' => "Philippines: Soccsksargen (Region XII)", + 'PH-SOR' => "Philippines: Sorsogon", + 'PH-SCO' => "Philippines: South Cotabato", + 'PH-SLE' => "Philippines: Southern Leyte", + 'PH-SUK' => "Philippines: Sultan Kudarat", + 'PH-SLU' => "Philippines: Sulu", + 'PH-SUN' => "Philippines: Surigao del Norte", + 'PH-SUR' => "Philippines: Surigao del Sur", + 'PH-TAR' => "Philippines: Tarlac", + 'PH-TAW' => "Philippines: Tawi-Tawi", + 'PH-WSA' => "Philippines: Western Samar", + 'PH-06' => "Philippines: Western Visayas (Region VI)", + 'PH-ZMB' => "Philippines: Zambales", + 'PH-09' => "Philippines: Zamboanga Peninsula (Region IX)", + 'PH-ZSI' => "Philippines: Zamboanga Sibugay", + 'PH-ZAN' => "Philippines: Zamboanga del Norte", + 'PH-ZAS' => "Philippines: Zamboanga del Sur", + + '--PL' => "", '-PL' => "Poland", + 'PL-DS' => "Poland: Dolnośląskie", + 'PL-KP' => "Poland: Kujawsko-pomorskie", + 'PL-LU' => "Poland: Lubelskie", + 'PL-LB' => "Poland: Lubuskie", + 'PL-MZ' => "Poland: Mazowieckie", + 'PL-MA' => "Poland: Małopolskie", + 'PL-OP' => "Poland: Opolskie", + 'PL-PK' => "Poland: Podkarpackie", + 'PL-PD' => "Poland: Podlaskie", + 'PL-PM' => "Poland: Pomorskie", + 'PL-WN' => "Poland: Warmińsko-mazurskie", + 'PL-WP' => "Poland: Wielkopolskie", + 'PL-ZP' => "Poland: Zachodniopomorskie", + 'PL-LD' => "Poland: Łódzkie", + 'PL-SL' => "Poland: Śląskie", + 'PL-SK' => "Poland: Świętokrzyskie", + + '--PT' => "", '-PT' => "Portugal", + 'PT-01' => "Portugal: Aveiro", + 'PT-02' => "Portugal: Beja", + 'PT-03' => "Portugal: Braga", + 'PT-04' => "Portugal: Bragança", + 'PT-05' => "Portugal: Castelo Branco", + 'PT-06' => "Portugal: Coimbra", + 'PT-08' => "Portugal: Faro", + 'PT-09' => "Portugal: Guarda", + 'PT-10' => "Portugal: Leiria", + 'PT-11' => "Portugal: Lisboa", + 'PT-12' => "Portugal: Portalegre", + 'PT-13' => "Portugal: Porto", + 'PT-30' => "Portugal: Região Autónoma da Madeira", + 'PT-20' => "Portugal: Região Autónoma dos Açores", + 'PT-14' => "Portugal: Santarém", + 'PT-15' => "Portugal: Setúbal", + 'PT-16' => "Portugal: Viana do Castelo", + 'PT-17' => "Portugal: Vila Real", + 'PT-18' => "Portugal: Viseu", + 'PT-07' => "Portugal: Évora", + + '--RO' => "", '-RO' => "Romania", + 'RO-AB' => "Romania: Alba", + 'RO-AR' => "Romania: Arad", + 'RO-AG' => "Romania: Argeș", + 'RO-BC' => "Romania: Bacău", + 'RO-BH' => "Romania: Bihor", + 'RO-BN' => "Romania: Bistrița-Năsăud", + 'RO-BT' => "Romania: Botoșani", + 'RO-BV' => "Romania: Brașov", + 'RO-BR' => "Romania: Brăila", + 'RO-B' => "Romania: București", + 'RO-BZ' => "Romania: Buzău", + 'RO-CS' => "Romania: Caraș-Severin", + 'RO-CJ' => "Romania: Cluj", + 'RO-CT' => "Romania: Constanța", + 'RO-CV' => "Romania: Covasna", + 'RO-CL' => "Romania: Călărași", + 'RO-DJ' => "Romania: Dolj", + 'RO-DB' => "Romania: Dâmbovița", + 'RO-GL' => "Romania: Galați", + 'RO-GR' => "Romania: Giurgiu", + 'RO-GJ' => "Romania: Gorj", + 'RO-HR' => "Romania: Harghita", + 'RO-HD' => "Romania: Hunedoara", + 'RO-IL' => "Romania: Ialomița", + 'RO-IS' => "Romania: Iași", + 'RO-IF' => "Romania: Ilfov", + 'RO-MM' => "Romania: Maramureș", + 'RO-MH' => "Romania: Mehedinți", + 'RO-MS' => "Romania: Mureș", + 'RO-NT' => "Romania: Neamț", + 'RO-OT' => "Romania: Olt", + 'RO-PH' => "Romania: Prahova", + 'RO-SM' => "Romania: Satu Mare", + 'RO-SB' => "Romania: Sibiu", + 'RO-SV' => "Romania: Suceava", + 'RO-SJ' => "Romania: Sălaj", + 'RO-TR' => "Romania: Teleorman", + 'RO-TM' => "Romania: Timiș", + 'RO-TL' => "Romania: Tulcea", + 'RO-VS' => "Romania: Vaslui", + 'RO-VN' => "Romania: Vrancea", + 'RO-VL' => "Romania: Vâlcea", + + '--RU' => "", '-RU' => "Russian Federation", + 'RU-AD' => "Russian Federation: Adygeya, Respublika", + 'RU-AL' => "Russian Federation: Altay, Respublika", + 'RU-ALT' => "Russian Federation: Altayskiy kray", + 'RU-AMU' => "Russian Federation: Amurskaya oblast'", + 'RU-ARK' => "Russian Federation: Arkhangel'skaya oblast'", + 'RU-AST' => "Russian Federation: Astrakhanskaya oblast'", + 'RU-BA' => "Russian Federation: Bashkortostan, Respublika", + 'RU-BEL' => "Russian Federation: Belgorodskaya oblast'", + 'RU-BRY' => "Russian Federation: Bryanskaya oblast'", + 'RU-BU' => "Russian Federation: Buryatiya, Respublika", + 'RU-CE' => "Russian Federation: Chechenskaya Respublika", + 'RU-CHE' => "Russian Federation: Chelyabinskaya oblast'", + 'RU-CHU' => "Russian Federation: Chukotskiy avtonomnyy okrug", + 'RU-CU' => "Russian Federation: Chuvashskaya Respublika", + 'RU-DA' => "Russian Federation: Dagestan, Respublika", + 'RU-IRK' => "Russian Federation: Irkutiskaya oblast'", + 'RU-IVA' => "Russian Federation: Ivanovskaya oblast'", + 'RU-KB' => "Russian Federation: Kabardino-Balkarskaya Respublika", + 'RU-KGD' => "Russian Federation: Kaliningradskaya oblast'", + 'RU-KL' => "Russian Federation: Kalmykiya, Respublika", + 'RU-KLU' => "Russian Federation: Kaluzhskaya oblast'", + 'RU-KAM' => "Russian Federation: Kamchatskiy kray", + 'RU-KC' => "Russian Federation: Karachayevo-Cherkesskaya Respublika", + 'RU-KR' => "Russian Federation: Kareliya, Respublika", + 'RU-KEM' => "Russian Federation: Kemerovskaya oblast'", + 'RU-KHA' => "Russian Federation: Khabarovskiy kray", + 'RU-KK' => "Russian Federation: Khakasiya, Respublika", + 'RU-KHM' => "Russian Federation: Khanty-Mansiysky avtonomnyy okrug-Yugra", + 'RU-KIR' => "Russian Federation: Kirovskaya oblast'", + 'RU-KO' => "Russian Federation: Komi, Respublika", + 'RU-KOS' => "Russian Federation: Kostromskaya oblast'", + 'RU-KDA' => "Russian Federation: Krasnodarskiy kray", + 'RU-KYA' => "Russian Federation: Krasnoyarskiy kray", + 'RU-KGN' => "Russian Federation: Kurganskaya oblast'", + 'RU-KRS' => "Russian Federation: Kurskaya oblast'", + 'RU-LEN' => "Russian Federation: Leningradskaya oblast'", + 'RU-LIP' => "Russian Federation: Lipetskaya oblast'", + 'RU-MAG' => "Russian Federation: Magadanskaya oblast'", + 'RU-ME' => "Russian Federation: Mariy El, Respublika", + 'RU-MO' => "Russian Federation: Mordoviya, Respublika", + 'RU-MOS' => "Russian Federation: Moskovskaya oblast'", + 'RU-MOW' => "Russian Federation: Moskva", + 'RU-MUR' => "Russian Federation: Murmanskaya oblast'", + 'RU-NEN' => "Russian Federation: Nenetskiy avtonomnyy okrug", + 'RU-NIZ' => "Russian Federation: Nizhegorodskaya oblast'", + 'RU-NGR' => "Russian Federation: Novgorodskaya oblast'", + 'RU-NVS' => "Russian Federation: Novosibirskaya oblast'", + 'RU-OMS' => "Russian Federation: Omskaya oblast'", + 'RU-ORE' => "Russian Federation: Orenburgskaya oblast'", + 'RU-ORL' => "Russian Federation: Orlovskaya oblast'", + 'RU-PNZ' => "Russian Federation: Penzenskaya oblast'", + 'RU-PER' => "Russian Federation: Permskiy kray", + 'RU-PRI' => "Russian Federation: Primorskiy kray", + 'RU-PSK' => "Russian Federation: Pskovskaya oblast'", + 'RU-IN' => "Russian Federation: Respublika Ingushetiya", + 'RU-ROS' => "Russian Federation: Rostovskaya oblast'", + 'RU-RYA' => "Russian Federation: Ryazanskaya oblast'", + 'RU-SA' => "Russian Federation: Sakha, Respublika [Yakutiya]", + 'RU-SAK' => "Russian Federation: Sakhalinskaya oblast'", + 'RU-SAM' => "Russian Federation: Samaraskaya oblast'", + 'RU-SPE' => "Russian Federation: Sankt-Peterburg", + 'RU-SAR' => "Russian Federation: Saratovskaya oblast'", + 'RU-SE' => "Russian Federation: Severnaya Osetiya-Alaniya, Respublika", + 'RU-SMO' => "Russian Federation: Smolenskaya oblast'", + 'RU-STA' => "Russian Federation: Stavropol'skiy kray", + 'RU-SVE' => "Russian Federation: Sverdlovskaya oblast'", + 'RU-TAM' => "Russian Federation: Tambovskaya oblast'", + 'RU-TA' => "Russian Federation: Tatarstan, Respublika", + 'RU-TOM' => "Russian Federation: Tomskaya oblast'", + 'RU-TUL' => "Russian Federation: Tul'skaya oblast'", + 'RU-TVE' => "Russian Federation: Tverskaya oblast'", + 'RU-TYU' => "Russian Federation: Tyumenskaya oblast'", + 'RU-TY' => "Russian Federation: Tyva, Respublika [Tuva]", + 'RU-UD' => "Russian Federation: Udmurtskaya Respublika", + 'RU-ULY' => "Russian Federation: Ul'yanovskaya oblast'", + 'RU-VLA' => "Russian Federation: Vladimirskaya oblast'", + 'RU-VGG' => "Russian Federation: Volgogradskaya oblast'", + 'RU-VLG' => "Russian Federation: Vologodskaya oblast'", + 'RU-VOR' => "Russian Federation: Voronezhskaya oblast'", + 'RU-YAN' => "Russian Federation: Yamalo-Nenetskiy avtonomnyy okrug", + 'RU-YAR' => "Russian Federation: Yaroslavskaya oblast'", + 'RU-YEV' => "Russian Federation: Yevreyskaya avtonomnaya oblast'", + 'RU-ZAB' => "Russian Federation: Zabajkal'skij kraj", + + '--SK' => "", '-SK' => "Slovakia", + 'SK-BC' => "Slovakia: Banskobystrický kraj", + 'SK-BL' => "Slovakia: Bratislavský kraj", + 'SK-KI' => "Slovakia: Košický kraj", + 'SK-NI' => "Slovakia: Nitriansky kraj", + 'SK-PV' => "Slovakia: Prešovský kraj", + 'SK-TC' => "Slovakia: Trenčiansky kraj", + 'SK-TA' => "Slovakia: Trnavský kraj", + 'SK-ZI' => "Slovakia: Žilinský kraj", + + '--SI' => "", '-SI' => "Slovenia", + 'SI-001' => "Slovenia: Ajdovščina", + 'SI-195' => "Slovenia: Apače", + 'SI-002' => "Slovenia: Beltinci", + 'SI-148' => "Slovenia: Benedikt", + 'SI-149' => "Slovenia: Bistrica ob Sotli", + 'SI-003' => "Slovenia: Bled", + 'SI-150' => "Slovenia: Bloke", + 'SI-004' => "Slovenia: Bohinj", + 'SI-005' => "Slovenia: Borovnica", + 'SI-006' => "Slovenia: Bovec", + 'SI-151' => "Slovenia: Braslovče", + 'SI-007' => "Slovenia: Brda", + 'SI-008' => "Slovenia: Brezovica", + 'SI-009' => "Slovenia: Brežice", + 'SI-152' => "Slovenia: Cankova", + 'SI-011' => "Slovenia: Celje", + 'SI-012' => "Slovenia: Cerklje na Gorenjskem", + 'SI-013' => "Slovenia: Cerknica", + 'SI-014' => "Slovenia: Cerkno", + 'SI-153' => "Slovenia: Cerkvenjak", + 'SI-196' => "Slovenia: Cirkulane", + 'SI-018' => "Slovenia: Destrnik", + 'SI-019' => "Slovenia: Divača", + 'SI-154' => "Slovenia: Dobje", + 'SI-020' => "Slovenia: Dobrepolje", + 'SI-155' => "Slovenia: Dobrna", + 'SI-021' => "Slovenia: Dobrova-Polhov Gradec", + 'SI-156' => "Slovenia: Dobrovnik/Dobronak", + 'SI-022' => "Slovenia: Dol pri Ljubljani", + 'SI-157' => "Slovenia: Dolenjske Toplice", + 'SI-023' => "Slovenia: Domžale", + 'SI-024' => "Slovenia: Dornava", + 'SI-025' => "Slovenia: Dravograd", + 'SI-026' => "Slovenia: Duplek", + 'SI-027' => "Slovenia: Gorenja vas-Poljane", + 'SI-028' => "Slovenia: Gorišnica", + 'SI-207' => "Slovenia: Gorje", + 'SI-029' => "Slovenia: Gornja Radgona", + 'SI-030' => "Slovenia: Gornji Grad", + 'SI-031' => "Slovenia: Gornji Petrovci", + 'SI-158' => "Slovenia: Grad", + 'SI-032' => "Slovenia: Grosuplje", + 'SI-159' => "Slovenia: Hajdina", + 'SI-161' => "Slovenia: Hodoš/Hodos", + 'SI-162' => "Slovenia: Horjul", + 'SI-160' => "Slovenia: Hoče-Slivnica", + 'SI-034' => "Slovenia: Hrastnik", + 'SI-035' => "Slovenia: Hrpelje-Kozina", + 'SI-036' => "Slovenia: Idrija", + 'SI-037' => "Slovenia: Ig", + 'SI-038' => "Slovenia: Ilirska Bistrica", + 'SI-039' => "Slovenia: Ivančna Gorica", + 'SI-040' => "Slovenia: Izola/Isola", + 'SI-041' => "Slovenia: Jesenice", + 'SI-163' => "Slovenia: Jezersko", + 'SI-042' => "Slovenia: Juršinci", + 'SI-043' => "Slovenia: Kamnik", + 'SI-044' => "Slovenia: Kanal", + 'SI-045' => "Slovenia: Kidričevo", + 'SI-046' => "Slovenia: Kobarid", + 'SI-047' => "Slovenia: Kobilje", + 'SI-049' => "Slovenia: Komen", + 'SI-164' => "Slovenia: Komenda", + 'SI-050' => "Slovenia: Koper/Capodistria", + 'SI-197' => "Slovenia: Kosanjevica na Krki", + 'SI-165' => "Slovenia: Kostel", + 'SI-051' => "Slovenia: Kozje", + 'SI-048' => "Slovenia: Kočevje", + 'SI-052' => "Slovenia: Kranj", + 'SI-053' => "Slovenia: Kranjska Gora", + 'SI-166' => "Slovenia: Križevci", + 'SI-054' => "Slovenia: Krško", + 'SI-055' => "Slovenia: Kungota", + 'SI-056' => "Slovenia: Kuzma", + 'SI-057' => "Slovenia: Laško", + 'SI-058' => "Slovenia: Lenart", + 'SI-059' => "Slovenia: Lendava/Lendva", + 'SI-060' => "Slovenia: Litija", + 'SI-061' => "Slovenia: Ljubljana", + 'SI-062' => "Slovenia: Ljubno", + 'SI-063' => "Slovenia: Ljutomer", + 'SI-208' => "Slovenia: Log-Dragomer", + 'SI-064' => "Slovenia: Logatec", + 'SI-167' => "Slovenia: Lovrenc na Pohorju", + 'SI-065' => "Slovenia: Loška dolina", + 'SI-066' => "Slovenia: Loški Potok", + 'SI-068' => "Slovenia: Lukovica", + 'SI-067' => "Slovenia: Luče", + 'SI-069' => "Slovenia: Majšperk", + 'SI-198' => "Slovenia: Makole", + 'SI-070' => "Slovenia: Maribor", + 'SI-168' => "Slovenia: Markovci", + 'SI-071' => "Slovenia: Medvode", + 'SI-072' => "Slovenia: Mengeš", + 'SI-073' => "Slovenia: Metlika", + 'SI-074' => "Slovenia: Mežica", + 'SI-169' => "Slovenia: Miklavž na Dravskem polju", + 'SI-075' => "Slovenia: Miren-Kostanjevica", + 'SI-170' => "Slovenia: Mirna Peč", + 'SI-076' => "Slovenia: Mislinja", + 'SI-199' => "Slovenia: Mokronog-Trebelno", + 'SI-078' => "Slovenia: Moravske Toplice", + 'SI-077' => "Slovenia: Moravče", + 'SI-079' => "Slovenia: Mozirje", + 'SI-080' => "Slovenia: Murska Sobota", + 'SI-081' => "Slovenia: Muta", + 'SI-082' => "Slovenia: Naklo", + 'SI-083' => "Slovenia: Nazarje", + 'SI-084' => "Slovenia: Nova Gorica", + 'SI-085' => "Slovenia: Novo mesto", + 'SI-086' => "Slovenia: Odranci", + 'SI-171' => "Slovenia: Oplotnica", + 'SI-087' => "Slovenia: Ormož", + 'SI-088' => "Slovenia: Osilnica", + 'SI-089' => "Slovenia: Pesnica", + 'SI-090' => "Slovenia: Piran/Pirano", + 'SI-091' => "Slovenia: Pivka", + 'SI-172' => "Slovenia: Podlehnik", + 'SI-093' => "Slovenia: Podvelka", + 'SI-092' => "Slovenia: Podčetrtek", + 'SI-200' => "Slovenia: Poljčane", + 'SI-173' => "Slovenia: Polzela", + 'SI-094' => "Slovenia: Postojna", + 'SI-174' => "Slovenia: Prebold", + 'SI-095' => "Slovenia: Preddvor", + 'SI-175' => "Slovenia: Prevalje", + 'SI-096' => "Slovenia: Ptuj", + 'SI-097' => "Slovenia: Puconci", + 'SI-100' => "Slovenia: Radenci", + 'SI-099' => "Slovenia: Radeče", + 'SI-101' => "Slovenia: Radlje ob Dravi", + 'SI-102' => "Slovenia: Radovljica", + 'SI-103' => "Slovenia: Ravne na Koroškem", + 'SI-176' => "Slovenia: Razkrižje", + 'SI-098' => "Slovenia: Rače-Fram", + 'SI-201' => "Slovenia: Renče-Vogrsko", + 'SI-209' => "Slovenia: Rečica ob Savinji", + 'SI-104' => "Slovenia: Ribnica", + 'SI-177' => "Slovenia: Ribnica na Pohorju", + 'SI-107' => "Slovenia: Rogatec", + 'SI-106' => "Slovenia: Rogaška Slatina", + 'SI-105' => "Slovenia: Rogašovci", + 'SI-108' => "Slovenia: Ruše", + 'SI-178' => "Slovenia: Selnica ob Dravi", + 'SI-109' => "Slovenia: Semič", + 'SI-110' => "Slovenia: Sevnica", + 'SI-111' => "Slovenia: Sežana", + 'SI-112' => "Slovenia: Slovenj Gradec", + 'SI-113' => "Slovenia: Slovenska Bistrica", + 'SI-114' => "Slovenia: Slovenske Konjice", + 'SI-179' => "Slovenia: Sodražica", + 'SI-180' => "Slovenia: Solčava", + 'SI-202' => "Slovenia: Središče ob Dravi", + 'SI-115' => "Slovenia: Starče", + 'SI-203' => "Slovenia: Straža", + 'SI-181' => "Slovenia: Sveta Ana", + 'SI-182' => "Slovenia: Sveta Andraž v Slovenskih Goricah", + 'SI-204' => "Slovenia: Sveta Trojica v Slovenskih Goricah", + 'SI-116' => "Slovenia: Sveti Jurij", + 'SI-210' => "Slovenia: Sveti Jurij v Slovenskih Goricah", + 'SI-205' => "Slovenia: Sveti Tomaž", + 'SI-184' => "Slovenia: Tabor", + 'SI-010' => "Slovenia: Tišina", + 'SI-128' => "Slovenia: Tolmin", + 'SI-129' => "Slovenia: Trbovlje", + 'SI-130' => "Slovenia: Trebnje", + 'SI-185' => "Slovenia: Trnovska vas", + 'SI-186' => "Slovenia: Trzin", + 'SI-131' => "Slovenia: Tržič", + 'SI-132' => "Slovenia: Turnišče", + 'SI-133' => "Slovenia: Velenje", + 'SI-187' => "Slovenia: Velika Polana", + 'SI-134' => "Slovenia: Velike Lašče", + 'SI-188' => "Slovenia: Veržej", + 'SI-135' => "Slovenia: Videm", + 'SI-136' => "Slovenia: Vipava", + 'SI-137' => "Slovenia: Vitanje", + 'SI-138' => "Slovenia: Vodice", + 'SI-139' => "Slovenia: Vojnik", + 'SI-189' => "Slovenia: Vransko", + 'SI-140' => "Slovenia: Vrhnika", + 'SI-141' => "Slovenia: Vuzenica", + 'SI-142' => "Slovenia: Zagorje ob Savi", + 'SI-143' => "Slovenia: Zavrč", + 'SI-144' => "Slovenia: Zreče", + 'SI-015' => "Slovenia: Črenšovci", + 'SI-016' => "Slovenia: Črna na Koroškem", + 'SI-017' => "Slovenia: Črnomelj", + 'SI-033' => "Slovenia: Šalovci", + 'SI-183' => "Slovenia: Šempeter-Vrtojba", + 'SI-118' => "Slovenia: Šentilj", + 'SI-119' => "Slovenia: Šentjernej", + 'SI-120' => "Slovenia: Šentjur", + 'SI-211' => "Slovenia: Šentrupert", + 'SI-117' => "Slovenia: Šenčur", + 'SI-121' => "Slovenia: Škocjan", + 'SI-122' => "Slovenia: Škofja Loka", + 'SI-123' => "Slovenia: Škofljica", + 'SI-124' => "Slovenia: Šmarje pri Jelšah", + 'SI-206' => "Slovenia: Šmarjeske Topliče", + 'SI-125' => "Slovenia: Šmartno ob Paki", + 'SI-194' => "Slovenia: Šmartno pri Litiji", + 'SI-126' => "Slovenia: Šoštanj", + 'SI-127' => "Slovenia: Štore", + 'SI-190' => "Slovenia: Žalec", + 'SI-146' => "Slovenia: Železniki", + 'SI-191' => "Slovenia: Žetale", + 'SI-147' => "Slovenia: Žiri", + 'SI-192' => "Slovenia: Žirovnica", + 'SI-193' => "Slovenia: Žužemberk", + + '--ZA' => "", '-ZA' => "South Africa", + 'ZA-EC' => "South Africa: Eastern Cape", + 'ZA-FS' => "South Africa: Free State", + 'ZA-GT' => "South Africa: Gauteng", + 'ZA-NL' => "South Africa: Kwazulu-Natal", + 'ZA-LP' => "South Africa: Limpopo", + 'ZA-MP' => "South Africa: Mpumalanga", + 'ZA-NW' => "South Africa: North-West (South Africa)", + 'ZA-NC' => "South Africa: Northern Cape", + 'ZA-WC' => "South Africa: Western Cape", + + '--ES' => "", '-ES' => "Spain", + 'ES-C' => "Spain: A Coruña", + 'ES-AB' => "Spain: Albacete", + 'ES-A' => "Spain: Alicante", + 'ES-AL' => "Spain: Almería", + 'ES-AN' => "Spain: Andalucía", + 'ES-AR' => "Spain: Aragón", + 'ES-O' => "Spain: Asturias", + 'ES-AS' => "Spain: Asturias, Principado de", + 'ES-BA' => "Spain: Badajoz", + 'ES-PM' => "Spain: Balears", + 'ES-B' => "Spain: Barcelona", + 'ES-BU' => "Spain: Burgos", + 'ES-CN' => "Spain: Canarias", + 'ES-S' => "Spain: Cantabria", + 'ES-CS' => "Spain: Castellón", + 'ES-CL' => "Spain: Castilla y León", + 'ES-CM' => "Spain: Castilla-La Mancha", + 'ES-CT' => "Spain: Catalunya", + 'ES-CE' => "Spain: Ceuta", + 'ES-CR' => "Spain: Ciudad Real", + 'ES-CU' => "Spain: Cuenca", + 'ES-CC' => "Spain: Cáceres", + 'ES-CA' => "Spain: Cádiz", + 'ES-CO' => "Spain: Córdoba", + 'ES-EX' => "Spain: Extremadura", + 'ES-GA' => "Spain: Galicia", + 'ES-GI' => "Spain: Girona", + 'ES-GR' => "Spain: Granada", + 'ES-GU' => "Spain: Guadalajara", + 'ES-SS' => "Spain: Guipúzcoa / Gipuzkoa", + 'ES-H' => "Spain: Huelva", + 'ES-HU' => "Spain: Huesca", + 'ES-IB' => "Spain: Illes Balears", + 'ES-J' => "Spain: Jaén", + 'ES-LO' => "Spain: La Rioja", + 'ES-GC' => "Spain: Las Palmas", + 'ES-LE' => "Spain: León", + 'ES-L' => "Spain: Lleida", + 'ES-LU' => "Spain: Lugo", + 'ES-M' => "Spain: Madrid", + 'ES-MD' => "Spain: Madrid, Comunidad de", + 'ES-ML' => "Spain: Melilla", + 'ES-MU' => "Spain: Murcia", + 'ES-MC' => "Spain: Murcia, Región de", + 'ES-MA' => "Spain: Málaga", + 'ES-NA' => "Spain: Navarra / Nafarroa", + 'ES-NC' => "Spain: Navarra, Comunidad Foral de / Nafarroako Foru Komunitatea", + 'ES-OR' => "Spain: Ourense", + 'ES-P' => "Spain: Palencia", + 'ES-PV' => "Spain: País Vasco / Euskal Herria", + 'ES-PO' => "Spain: Pontevedra", + 'ES-SA' => "Spain: Salamanca", + 'ES-TF' => "Spain: Santa Cruz de Tenerife", + 'ES-SG' => "Spain: Segovia", + 'ES-SE' => "Spain: Sevilla", + 'ES-SO' => "Spain: Soria", + 'ES-T' => "Spain: Tarragona", + 'ES-TE' => "Spain: Teruel", + 'ES-TO' => "Spain: Toledo", + 'ES-V' => "Spain: Valencia / València", + 'ES-VC' => "Spain: Valenciana, Comunidad / Valenciana, Comunitat", + 'ES-VA' => "Spain: Valladolid", + 'ES-BI' => "Spain: Vizcayaa / Bizkaia", + 'ES-ZA' => "Spain: Zamora", + 'ES-Z' => "Spain: Zaragoza", + 'ES-VI' => "Spain: Álava", + 'ES-AV' => "Spain: Ávila", + + '--SE' => "", '-SE' => "Sweden", + 'SE-K' => "Sweden: Blekinge län", + 'SE-W' => "Sweden: Dalarnas län", + 'SE-I' => "Sweden: Gotlands län", + 'SE-X' => "Sweden: Gävleborgs län", + 'SE-N' => "Sweden: Hallands län", + 'SE-Z' => "Sweden: Jämtlande län", + 'SE-F' => "Sweden: Jönköpings län", + 'SE-H' => "Sweden: Kalmar län", + 'SE-G' => "Sweden: Kronobergs län", + 'SE-BD' => "Sweden: Norrbottens län", + 'SE-M' => "Sweden: Skåne län", + 'SE-AB' => "Sweden: Stockholms län", + 'SE-D' => "Sweden: Södermanlands län", + 'SE-C' => "Sweden: Uppsala län", + 'SE-S' => "Sweden: Värmlands län", + 'SE-AC' => "Sweden: Västerbottens län", + 'SE-Y' => "Sweden: Västernorrlands län", + 'SE-U' => "Sweden: Västmanlands län", + 'SE-O' => "Sweden: Västra Götalands län", + 'SE-T' => "Sweden: Örebro län", + 'SE-E' => "Sweden: Östergötlands län", + + '--CH' => "", '-CH' => "Switzerland", + 'CH-AG' => "Switzerland: Aargau", + 'CH-AR' => "Switzerland: Appenzell Ausserrhoden", + 'CH-AI' => "Switzerland: Appenzell Innerrhoden", + 'CH-BL' => "Switzerland: Basel-Landschaft", + 'CH-BS' => "Switzerland: Basel-Stadt", + 'CH-BE' => "Switzerland: Bern", + 'CH-FR' => "Switzerland: Fribourg", + 'CH-GE' => "Switzerland: Genève", + 'CH-GL' => "Switzerland: Glarus", + 'CH-GR' => "Switzerland: Graubünden", + 'CH-JU' => "Switzerland: Jura", + 'CH-LU' => "Switzerland: Luzern", + 'CH-NE' => "Switzerland: Neuchâtel", + 'CH-NW' => "Switzerland: Nidwalden", + 'CH-OW' => "Switzerland: Obwalden", + 'CH-SG' => "Switzerland: Sankt Gallen", + 'CH-SH' => "Switzerland: Schaffhausen", + 'CH-SZ' => "Switzerland: Schwyz", + 'CH-SO' => "Switzerland: Solothurn", + 'CH-TG' => "Switzerland: Thurgau", + 'CH-TI' => "Switzerland: Ticino", + 'CH-UR' => "Switzerland: Uri", + 'CH-VS' => "Switzerland: Valais", + 'CH-VD' => "Switzerland: Vaud", + 'CH-ZG' => "Switzerland: Zug", + 'CH-ZH' => "Switzerland: Zürich", + + '--TW' => "", '-TW' => "Taiwan", + 'TW-CHA' => "Taiwan: Changhua", + 'TW-CYI' => "Taiwan: Chiay City", + 'TW-CYQ' => "Taiwan: Chiayi", + 'TW-HSQ' => "Taiwan: Hsinchu", + 'TW-HSZ' => "Taiwan: Hsinchui City", + 'TW-HUA' => "Taiwan: Hualien", + 'TW-ILA' => "Taiwan: Ilan", + 'TW-KHQ' => "Taiwan: Kaohsiung", + 'TW-KHH' => "Taiwan: Kaohsiung City", + 'TW-KEE' => "Taiwan: Keelung City", + 'TW-MIA' => "Taiwan: Miaoli", + 'TW-NAN' => "Taiwan: Nantou", + 'TW-PEN' => "Taiwan: Penghu", + 'TW-PIF' => "Taiwan: Pingtung", + 'TW-TXQ' => "Taiwan: Taichung", + 'TW-TXG' => "Taiwan: Taichung City", + 'TW-TNQ' => "Taiwan: Tainan", + 'TW-TNN' => "Taiwan: Tainan City", + 'TW-TPQ' => "Taiwan: Taipei", + 'TW-TPE' => "Taiwan: Taipei City", + 'TW-TTT' => "Taiwan: Taitung", + 'TW-TAO' => "Taiwan: Taoyuan", + 'TW-YUN' => "Taiwan: Yunlin", + + '--TH' => "", '-TH' => "Thailand", + 'TH-37' => "Thailand: Amnat Charoen", + 'TH-15' => "Thailand: Ang Thong", + 'TH-31' => "Thailand: Buri Ram", + 'TH-24' => "Thailand: Chachoengsao", + 'TH-18' => "Thailand: Chai Nat", + 'TH-36' => "Thailand: Chaiyaphum", + 'TH-22' => "Thailand: Chanthaburi", + 'TH-50' => "Thailand: Chiang Mai", + 'TH-57' => "Thailand: Chiang Rai", + 'TH-20' => "Thailand: Chon Buri", + 'TH-86' => "Thailand: Chumphon", + 'TH-46' => "Thailand: Kalasin", + 'TH-62' => "Thailand: Kamphaeng Phet", + 'TH-71' => "Thailand: Kanchanaburi", + 'TH-40' => "Thailand: Khon Kaen", + 'TH-81' => "Thailand: Krabi", + 'TH-10' => "Thailand: Krung Thep Maha Nakhon Bangkok", + 'TH-52' => "Thailand: Lampang", + 'TH-51' => "Thailand: Lamphun", + 'TH-42' => "Thailand: Loei", + 'TH-16' => "Thailand: Lop Buri", + 'TH-58' => "Thailand: Mae Hong Son", + 'TH-44' => "Thailand: Maha Sarakham", + 'TH-49' => "Thailand: Mukdahan", + 'TH-26' => "Thailand: Nakhon Nayok", + 'TH-73' => "Thailand: Nakhon Pathom", + 'TH-48' => "Thailand: Nakhon Phanom", + 'TH-30' => "Thailand: Nakhon Ratchasima", + 'TH-60' => "Thailand: Nakhon Sawan", + 'TH-80' => "Thailand: Nakhon Si Thammarat", + 'TH-55' => "Thailand: Nan", + 'TH-96' => "Thailand: Narathiwat", + 'TH-39' => "Thailand: Nong Bua Lam Phu", + 'TH-43' => "Thailand: Nong Khai", + 'TH-12' => "Thailand: Nonthaburi", + 'TH-13' => "Thailand: Pathum Thani", + 'TH-94' => "Thailand: Pattani", + 'TH-82' => "Thailand: Phangnga", + 'TH-93' => "Thailand: Phatthalung", + 'TH-S' => "Thailand: Phatthaya", + 'TH-56' => "Thailand: Phayao", + 'TH-67' => "Thailand: Phetchabun", + 'TH-76' => "Thailand: Phetchaburi", + 'TH-66' => "Thailand: Phichit", + 'TH-65' => "Thailand: Phitsanulok", + 'TH-14' => "Thailand: Phra Nakhon Si Ayutthaya", + 'TH-54' => "Thailand: Phrae", + 'TH-83' => "Thailand: Phuket", + 'TH-25' => "Thailand: Prachin Buri", + 'TH-77' => "Thailand: Prachuap Khiri Khan", + 'TH-85' => "Thailand: Ranong", + 'TH-70' => "Thailand: Ratchaburi", + 'TH-21' => "Thailand: Rayong", + 'TH-45' => "Thailand: Roi Et", + 'TH-27' => "Thailand: Sa Kaeo", + 'TH-47' => "Thailand: Sakon Nakhon", + 'TH-11' => "Thailand: Samut Prakan", + 'TH-74' => "Thailand: Samut Sakhon", + 'TH-75' => "Thailand: Samut Songkhram", + 'TH-19' => "Thailand: Saraburi", + 'TH-91' => "Thailand: Satun", + 'TH-33' => "Thailand: Si Sa Ket", + 'TH-17' => "Thailand: Sing Buri", + 'TH-90' => "Thailand: Songkhla", + 'TH-64' => "Thailand: Sukhothai", + 'TH-72' => "Thailand: Suphan Buri", + 'TH-84' => "Thailand: Surat Thani", + 'TH-32' => "Thailand: Surin", + 'TH-63' => "Thailand: Tak", + 'TH-92' => "Thailand: Trang", + 'TH-23' => "Thailand: Trat", + 'TH-34' => "Thailand: Ubon Ratchathani", + 'TH-41' => "Thailand: Udon Thani", + 'TH-61' => "Thailand: Uthai Thani", + 'TH-53' => "Thailand: Uttaradit", + 'TH-95' => "Thailand: Yala", + 'TH-35' => "Thailand: Yasothon", + + '--TR' => "", '-TR' => "Turkey", + 'TR-01' => "Turkey: Adana", + 'TR-02' => "Turkey: Adıyaman", + 'TR-03' => "Turkey: Afyon", + 'TR-68' => "Turkey: Aksaray", + 'TR-05' => "Turkey: Amasya", + 'TR-06' => "Turkey: Ankara", + 'TR-07' => "Turkey: Antalya", + 'TR-75' => "Turkey: Ardahan", + 'TR-08' => "Turkey: Artvin", + 'TR-09' => "Turkey: Aydın", + 'TR-04' => "Turkey: Ağrı", + 'TR-10' => "Turkey: Balıkesir", + 'TR-74' => "Turkey: Bartın", + 'TR-72' => "Turkey: Batman", + 'TR-69' => "Turkey: Bayburt", + 'TR-11' => "Turkey: Bilecik", + 'TR-12' => "Turkey: Bingöl", + 'TR-13' => "Turkey: Bitlis", + 'TR-14' => "Turkey: Bolu", + 'TR-15' => "Turkey: Burdur", + 'TR-16' => "Turkey: Bursa", + 'TR-20' => "Turkey: Denizli", + 'TR-21' => "Turkey: Diyarbakır", + 'TR-81' => "Turkey: Düzce", + 'TR-22' => "Turkey: Edirne", + 'TR-23' => "Turkey: Elazığ", + 'TR-24' => "Turkey: Erzincan", + 'TR-25' => "Turkey: Erzurum", + 'TR-26' => "Turkey: Eskişehir", + 'TR-27' => "Turkey: Gaziantep", + 'TR-28' => "Turkey: Giresun", + 'TR-29' => "Turkey: Gümüşhane", + 'TR-30' => "Turkey: Hakkâri", + 'TR-31' => "Turkey: Hatay", + 'TR-32' => "Turkey: Isparta", + 'TR-76' => "Turkey: Iğdır", + 'TR-46' => "Turkey: Kahramanmaraş", + 'TR-78' => "Turkey: Karabük", + 'TR-70' => "Turkey: Karaman", + 'TR-36' => "Turkey: Kars", + 'TR-37' => "Turkey: Kastamonu", + 'TR-38' => "Turkey: Kayseri", + 'TR-79' => "Turkey: Kilis", + 'TR-41' => "Turkey: Kocaeli", + 'TR-42' => "Turkey: Konya", + 'TR-43' => "Turkey: Kütahya", + 'TR-39' => "Turkey: Kırklareli", + 'TR-71' => "Turkey: Kırıkkale", + 'TR-40' => "Turkey: Kırşehir", + 'TR-44' => "Turkey: Malatya", + 'TR-45' => "Turkey: Manisa", + 'TR-47' => "Turkey: Mardin", + 'TR-48' => "Turkey: Muğla", + 'TR-49' => "Turkey: Muş", + 'TR-50' => "Turkey: Nevşehir", + 'TR-51' => "Turkey: Niğde", + 'TR-52' => "Turkey: Ordu", + 'TR-80' => "Turkey: Osmaniye", + 'TR-53' => "Turkey: Rize", + 'TR-54' => "Turkey: Sakarya", + 'TR-55' => "Turkey: Samsun", + 'TR-56' => "Turkey: Siirt", + 'TR-57' => "Turkey: Sinop", + 'TR-58' => "Turkey: Sivas", + 'TR-59' => "Turkey: Tekirdağ", + 'TR-60' => "Turkey: Tokat", + 'TR-61' => "Turkey: Trabzon", + 'TR-62' => "Turkey: Tunceli", + 'TR-64' => "Turkey: Uşak", + 'TR-65' => "Turkey: Van", + 'TR-77' => "Turkey: Yalova", + 'TR-66' => "Turkey: Yozgat", + 'TR-67' => "Turkey: Zonguldak", + 'TR-17' => "Turkey: Çanakkale", + 'TR-18' => "Turkey: Çankırı", + 'TR-19' => "Turkey: Çorum", + 'TR-34' => "Turkey: İstanbul", + 'TR-35' => "Turkey: İzmir", + 'TR-33' => "Turkey: İçel", + 'TR-63' => "Turkey: Şanlıurfa", + 'TR-73' => "Turkey: Şırnak", + + '--UA' => "", '-UA' => "Ukraine", + 'UA-71' => "Ukraine: Cherkas'ka Oblast'", + 'UA-74' => "Ukraine: Chernihivs'ka Oblast'", + 'UA-77' => "Ukraine: Chernivets'ka Oblast'", + 'UA-12' => "Ukraine: Dnipropetrovs'ka Oblast'", + 'UA-14' => "Ukraine: Donets'ka Oblast'", + 'UA-26' => "Ukraine: Ivano-Frankivs'ka Oblast'", + 'UA-63' => "Ukraine: Kharkivs'ka Oblast'", + 'UA-65' => "Ukraine: Khersons'ka Oblast'", + 'UA-68' => "Ukraine: Khmel'nyts'ka Oblast'", + 'UA-35' => "Ukraine: Kirovohrads'ka Oblast'", + 'UA-32' => "Ukraine: Kyïvs'ka Oblast'", + 'UA-30' => "Ukraine: Kyïvs'ka mis'ka rada", + 'UA-46' => "Ukraine: L'vivs'ka Oblast'", + 'UA-09' => "Ukraine: Luhans'ka Oblast'", + 'UA-48' => "Ukraine: Mykolaïvs'ka Oblast'", + 'UA-51' => "Ukraine: Odes'ka Oblast'", + 'UA-53' => "Ukraine: Poltavs'ka Oblast'", + 'UA-43' => "Ukraine: Respublika Krym", + 'UA-56' => "Ukraine: Rivnens'ka Oblast'", + 'UA-40' => "Ukraine: Sevastopol", + 'UA-59' => "Ukraine: Sums 'ka Oblast'", + 'UA-61' => "Ukraine: Ternopil's'ka Oblast'", + 'UA-05' => "Ukraine: Vinnyts'ka Oblast'", + 'UA-07' => "Ukraine: Volyns'ka Oblast'", + 'UA-21' => "Ukraine: Zakarpats'ka Oblast'", + 'UA-23' => "Ukraine: Zaporiz'ka Oblast'", + 'UA-18' => "Ukraine: Zhytomyrs'ka Oblast'", + + '--AE' => "", '-AE' => "United Arab Emirates", + 'AE-AJ' => "United Arab Emirates: 'Ajmān", + 'AE-AZ' => "United Arab Emirates: Abū Ȥaby [Abu Dhabi]", + 'AE-FU' => "United Arab Emirates: Al Fujayrah", + 'AE-SH' => "United Arab Emirates: Ash Shāriqah", + 'AE-DU' => "United Arab Emirates: Dubayy", + 'AE-RK' => "United Arab Emirates: Ra’s al Khaymah", + 'AE-UQ' => "United Arab Emirates: Umm al Qaywayn", + + '--GB' => "", '-GB' => "United Kingdom", + 'GB-ABE' => "United Kingdom: Aberdeen City", + 'GB-ABD' => "United Kingdom: Aberdeenshire", + 'GB-ANS' => "United Kingdom: Angus", + 'GB-ANT' => "United Kingdom: Antrim", + 'GB-ARD' => "United Kingdom: Ards", + 'GB-AGB' => "United Kingdom: Argyll and Bute", + 'GB-ARM' => "United Kingdom: Armagh", + 'GB-BLA' => "United Kingdom: Ballymena", + 'GB-BLY' => "United Kingdom: Ballymoney", + 'GB-BNB' => "United Kingdom: Banbridge", + 'GB-BDG' => "United Kingdom: Barking and Dagenham", + 'GB-BNE' => "United Kingdom: Barnet", + 'GB-BNS' => "United Kingdom: Barnsley", + 'GB-BAS' => "United Kingdom: Bath and North East Somerset", + 'GB-BDF' => "United Kingdom: Bedford", + 'GB-BFS' => "United Kingdom: Belfast", + 'GB-BEX' => "United Kingdom: Bexley", + 'GB-BIR' => "United Kingdom: Birmingham", + 'GB-BBD' => "United Kingdom: Blackburn with Darwen", + 'GB-BPL' => "United Kingdom: Blackpool", + 'GB-BGW' => "United Kingdom: Blaenau Gwent", + 'GB-BOL' => "United Kingdom: Bolton", + 'GB-BMH' => "United Kingdom: Bournemouth", + 'GB-BRC' => "United Kingdom: Bracknell Forest", + 'GB-BRD' => "United Kingdom: Bradford", + 'GB-BEN' => "United Kingdom: Brent", + 'GB-BGE' => "United Kingdom: Bridgend (Pen-y-bont ar Ogwr)", + 'GB-BNH' => "United Kingdom: Brighton and Hove", + 'GB-BST' => "United Kingdom: Bristol, City of", + 'GB-BRY' => "United Kingdom: Bromley", + 'GB-BKM' => "United Kingdom: Buckinghamshire", + 'GB-BUR' => "United Kingdom: Bury", + 'GB-CAY' => "United Kingdom: Caerphilly (Caerffili)", + 'GB-CLD' => "United Kingdom: Calderdale", + 'GB-CAM' => "United Kingdom: Cambridgeshire", + 'GB-CMD' => "United Kingdom: Camden", + 'GB-CRF' => "United Kingdom: Cardiff (Caerdydd)", + 'GB-CMN' => "United Kingdom: Carmarthenshire (Sir Gaerfyrddin)", + 'GB-CKF' => "United Kingdom: Carrickfergus", + 'GB-CSR' => "United Kingdom: Castlereagh", + 'GB-CBF' => "United Kingdom: Central Bedfordshire", + 'GB-CGN' => "United Kingdom: Ceredigion (Sir Ceredigion)", + 'GB-CHE' => "United Kingdom: Cheshire East", + 'GB-CHW' => "United Kingdom: Cheshire West and Chester", + 'GB-CLK' => "United Kingdom: Clackmannanshire", + 'GB-CLR' => "United Kingdom: Coleraine", + 'GB-CWY' => "United Kingdom: Conwy", + 'GB-CKT' => "United Kingdom: Cookstown", + 'GB-CON' => "United Kingdom: Cornwall", + 'GB-COV' => "United Kingdom: Coventry", + 'GB-CGV' => "United Kingdom: Craigavon", + 'GB-CRY' => "United Kingdom: Croydon", + 'GB-CMA' => "United Kingdom: Cumbria", + 'GB-DAL' => "United Kingdom: Darlington", + 'GB-DEN' => "United Kingdom: Denbighshire (Sir Ddinbych)", + 'GB-DER' => "United Kingdom: Derby", + 'GB-DBY' => "United Kingdom: Derbyshire", + 'GB-DRY' => "United Kingdom: Derry", + 'GB-DEV' => "United Kingdom: Devon", + 'GB-DNC' => "United Kingdom: Doncaster", + 'GB-DOR' => "United Kingdom: Dorset", + 'GB-DOW' => "United Kingdom: Down", + 'GB-DUD' => "United Kingdom: Dudley", + 'GB-DGY' => "United Kingdom: Dumfries and Galloway", + 'GB-DND' => "United Kingdom: Dundee City", + 'GB-DGN' => "United Kingdom: Dungannon", + 'GB-DUR' => "United Kingdom: Durham", + 'GB-EAL' => "United Kingdom: Ealing", + 'GB-EAY' => "United Kingdom: East Ayrshire", + 'GB-EDU' => "United Kingdom: East Dunbartonshire", + 'GB-ELN' => "United Kingdom: East Lothian", + 'GB-ERW' => "United Kingdom: East Renfrewshire", + 'GB-ERY' => "United Kingdom: East Riding of Yorkshire", + 'GB-ESX' => "United Kingdom: East Sussex", + 'GB-EDH' => "United Kingdom: Edinburgh, City of", + 'GB-ELS' => "United Kingdom: Eilean Siar", + 'GB-ENF' => "United Kingdom: Enfield", + 'GB-ENG' => "United Kingdom: England", + 'GB-EAW' => "United Kingdom: England and Wales", + 'GB-ESS' => "United Kingdom: Essex", + 'GB-FAL' => "United Kingdom: Falkirk", + 'GB-FER' => "United Kingdom: Fermanagh", + 'GB-FIF' => "United Kingdom: Fife", + 'GB-FLN' => "United Kingdom: Flintshire (Sir y Fflint)", + 'GB-GAT' => "United Kingdom: Gateshead", + 'GB-GLG' => "United Kingdom: Glasgow City", + 'GB-GLS' => "United Kingdom: Gloucestershire", + 'GB-GBN' => "United Kingdom: Great Britain", + 'GB-GRE' => "United Kingdom: Greenwich", + 'GB-GWN' => "United Kingdom: Gwynedd", + 'GB-HCK' => "United Kingdom: Hackney", + 'GB-HAL' => "United Kingdom: Halton", + 'GB-HMF' => "United Kingdom: Hammersmith and Fulham", + 'GB-HAM' => "United Kingdom: Hampshire", + 'GB-HRY' => "United Kingdom: Haringey", + 'GB-HRW' => "United Kingdom: Harrow", + 'GB-HPL' => "United Kingdom: Hartlepool", + 'GB-HAV' => "United Kingdom: Havering", + 'GB-HEF' => "United Kingdom: Herefordshire", + 'GB-HRT' => "United Kingdom: Hertfordshire", + 'GB-HLD' => "United Kingdom: Highland", + 'GB-HIL' => "United Kingdom: Hillingdon", + 'GB-HNS' => "United Kingdom: Hounslow", + 'GB-IVC' => "United Kingdom: Inverclyde", + 'GB-AGY' => "United Kingdom: Isle of Anglesey (Sir Ynys Môn)", + 'GB-IOW' => "United Kingdom: Isle of Wight", + 'GB-ISL' => "United Kingdom: Islington", + 'GB-KEC' => "United Kingdom: Kensington and Chelsea", + 'GB-KEN' => "United Kingdom: Kent", + 'GB-KHL' => "United Kingdom: Kingston upon Hull", + 'GB-KTT' => "United Kingdom: Kingston upon Thames", + 'GB-KIR' => "United Kingdom: Kirklees", + 'GB-KWL' => "United Kingdom: Knowsley", + 'GB-LBH' => "United Kingdom: Lambeth", + 'GB-LAN' => "United Kingdom: Lancashire", + 'GB-LRN' => "United Kingdom: Larne", + 'GB-LDS' => "United Kingdom: Leeds", + 'GB-LCE' => "United Kingdom: Leicester", + 'GB-LEC' => "United Kingdom: Leicestershire", + 'GB-LEW' => "United Kingdom: Lewisham", + 'GB-LMV' => "United Kingdom: Limavady", + 'GB-LIN' => "United Kingdom: Lincolnshire", + 'GB-LSB' => "United Kingdom: Lisburn", + 'GB-LIV' => "United Kingdom: Liverpool", + 'GB-LND' => "United Kingdom: London, City of", + 'GB-LUT' => "United Kingdom: Luton", + 'GB-MFT' => "United Kingdom: Magherafelt", + 'GB-MAN' => "United Kingdom: Manchester", + 'GB-MDW' => "United Kingdom: Medway", + 'GB-MTY' => "United Kingdom: Merthyr Tydfil (Merthyr Tudful)", + 'GB-MRT' => "United Kingdom: Merton", + 'GB-MDB' => "United Kingdom: Middlesbrough", + 'GB-MLN' => "United Kingdom: Midlothian", + 'GB-MIK' => "United Kingdom: Milton Keynes", + 'GB-MON' => "United Kingdom: Monmouthshire (Sir Fynwy)", + 'GB-MRY' => "United Kingdom: Moray", + 'GB-MYL' => "United Kingdom: Moyle", + 'GB-NTL' => "United Kingdom: Neath Port Talbot (Castell-nedd Port Talbot)", + 'GB-NET' => "United Kingdom: Newcastle upon Tyne", + 'GB-NWM' => "United Kingdom: Newham", + 'GB-NWP' => "United Kingdom: Newport (Casnewydd)", + 'GB-NYM' => "United Kingdom: Newry and Mourne", + 'GB-NTA' => "United Kingdom: Newtownabbey", + 'GB-NFK' => "United Kingdom: Norfolk", + 'GB-NAY' => "United Kingdom: North Ayrshire", + 'GB-NDN' => "United Kingdom: North Down", + 'GB-NEL' => "United Kingdom: North East Lincolnshire", + 'GB-NLK' => "United Kingdom: North Lanarkshire", + 'GB-NLN' => "United Kingdom: North Lincolnshire", + 'GB-NSM' => "United Kingdom: North Somerset", + 'GB-NTY' => "United Kingdom: North Tyneside", + 'GB-NYK' => "United Kingdom: North Yorkshire", + 'GB-NTH' => "United Kingdom: Northamptonshire", + 'GB-NIR' => "United Kingdom: Northern Ireland", + 'GB-NBL' => "United Kingdom: Northumberland", + 'GB-NGM' => "United Kingdom: Nottingham", + 'GB-NTT' => "United Kingdom: Nottinghamshire", + 'GB-OLD' => "United Kingdom: Oldham", + 'GB-OMH' => "United Kingdom: Omagh", + 'GB-ORK' => "United Kingdom: Orkney Islands", + 'GB-OXF' => "United Kingdom: Oxfordshire", + 'GB-PEM' => "United Kingdom: Pembrokeshire (Sir Benfro)", + 'GB-PKN' => "United Kingdom: Perth and Kinross", + 'GB-PTE' => "United Kingdom: Peterborough", + 'GB-PLY' => "United Kingdom: Plymouth", + 'GB-POL' => "United Kingdom: Poole", + 'GB-POR' => "United Kingdom: Portsmouth", + 'GB-POW' => "United Kingdom: Powys", + 'GB-RDG' => "United Kingdom: Reading", + 'GB-RDB' => "United Kingdom: Redbridge", + 'GB-RCC' => "United Kingdom: Redcar and Cleveland", + 'GB-RFW' => "United Kingdom: Renfrewshire", + 'GB-RCT' => "United Kingdom: Rhondda, Cynon, Taff (Rhondda, Cynon, Taf)", + 'GB-RIC' => "United Kingdom: Richmond upon Thames", + 'GB-RCH' => "United Kingdom: Rochdale", + 'GB-ROT' => "United Kingdom: Rotherham", + 'GB-RUT' => "United Kingdom: Rutland", + 'GB-SLF' => "United Kingdom: Salford", + 'GB-SAW' => "United Kingdom: Sandwell", + 'GB-SCT' => "United Kingdom: Scotland", + 'GB-SCB' => "United Kingdom: Scottish Borders, The", + 'GB-SFT' => "United Kingdom: Sefton", + 'GB-SHF' => "United Kingdom: Sheffield", + 'GB-ZET' => "United Kingdom: Shetland Islands", + 'GB-SHR' => "United Kingdom: Shropshire", + 'GB-SLG' => "United Kingdom: Slough", + 'GB-SOL' => "United Kingdom: Solihull", + 'GB-SOM' => "United Kingdom: Somerset", + 'GB-SAY' => "United Kingdom: South Ayrshire", + 'GB-SGC' => "United Kingdom: South Gloucestershire", + 'GB-SLK' => "United Kingdom: South Lanarkshire", + 'GB-STY' => "United Kingdom: South Tyneside", + 'GB-STH' => "United Kingdom: Southampton", + 'GB-SOS' => "United Kingdom: Southend-on-Sea", + 'GB-SWK' => "United Kingdom: Southwark", + 'GB-SHN' => "United Kingdom: St. Helens", + 'GB-STS' => "United Kingdom: Staffordshire", + 'GB-STG' => "United Kingdom: Stirling", + 'GB-SKP' => "United Kingdom: Stockport", + 'GB-STT' => "United Kingdom: Stockton-on-Tees", + 'GB-STE' => "United Kingdom: Stoke-on-Trent", + 'GB-STB' => "United Kingdom: Strabane", + 'GB-SFK' => "United Kingdom: Suffolk", + 'GB-SND' => "United Kingdom: Sunderland", + 'GB-SRY' => "United Kingdom: Surrey", + 'GB-STN' => "United Kingdom: Sutton", + 'GB-SWA' => "United Kingdom: Swansea (Abertawe)", + 'GB-SWD' => "United Kingdom: Swindon", + 'GB-TAM' => "United Kingdom: Tameside", + 'GB-TFW' => "United Kingdom: Telford and Wrekin", + 'GB-THR' => "United Kingdom: Thurrock", + 'GB-TOB' => "United Kingdom: Torbay", + 'GB-TOF' => "United Kingdom: Torfaen (Tor-faen)", + 'GB-TWH' => "United Kingdom: Tower Hamlets", + 'GB-TRF' => "United Kingdom: Trafford", + 'GB-UKM' => "United Kingdom: United Kingdom", + 'GB-VGL' => "United Kingdom: Vale of Glamorgan, The (Bro Morgannwg)", + 'GB-WKF' => "United Kingdom: Wakefield", + 'GB-WLS' => "United Kingdom: Wales", + 'GB-WLL' => "United Kingdom: Walsall", + 'GB-WFT' => "United Kingdom: Waltham Forest", + 'GB-WND' => "United Kingdom: Wandsworth", + 'GB-WRT' => "United Kingdom: Warrington", + 'GB-WAR' => "United Kingdom: Warwickshire", + 'GB-WBK' => "United Kingdom: West Berkshire", + 'GB-WDU' => "United Kingdom: West Dunbartonshire", + 'GB-WLN' => "United Kingdom: West Lothian", + 'GB-WSX' => "United Kingdom: West Sussex", + 'GB-WSM' => "United Kingdom: Westminster", + 'GB-WGN' => "United Kingdom: Wigan", + 'GB-WNM' => "United Kingdom: Windsor and Maidenhead", + 'GB-WRL' => "United Kingdom: Wirral", + 'GB-WOK' => "United Kingdom: Wokingham", + 'GB-WLV' => "United Kingdom: Wolverhampton", + 'GB-WOR' => "United Kingdom: Worcestershire", + 'GB-WRX' => "United Kingdom: Wrexham (Wrecsam)", + 'GB-YOR' => "United Kingdom: York", + + '--US' => "", '-US' => "United States", + 'US-AL' => "United States: Alabama", + 'US-AK' => "United States: Alaska", + 'US-AS' => "United States: American Samoa, Samoa Americana", + 'US-AZ' => "United States: Arizona", + 'US-AR' => "United States: Arkansas", + 'US-CA' => "United States: California", + 'US-CO' => "United States: Colorado", + 'US-CT' => "United States: Connecticut", + 'US-DE' => "United States: Delaware", + 'US-DC' => "United States: District of Columbia, Disricte de Columbia", + 'US-FL' => "United States: Florida", + 'US-GA' => "United States: Georgia, Geòrgia", + 'US-GU' => "United States: Guam", + 'US-HI' => "United States: Hawaii", + 'US-ID' => "United States: Idaho", + 'US-IL' => "United States: Illinois", + 'US-IN' => "United States: Indiana", + 'US-IA' => "United States: Iowa", + 'US-KS' => "United States: Kansas", + 'US-KY' => "United States: Kentucky", + 'US-LA' => "United States: Louisiana", + 'US-ME' => "United States: Maine", + 'US-MD' => "United States: Maryland", + 'US-MA' => "United States: Massachusetts", + 'US-MI' => "United States: Michigan", + 'US-MN' => "United States: Minnesota", + 'US-MS' => "United States: Mississippi", + 'US-MO' => "United States: Missouri", + 'US-MT' => "United States: Montana", + 'US-NE' => "United States: Nebraska", + 'US-NV' => "United States: Nevada", + 'US-NH' => "United States: New Hampshire", + 'US-NJ' => "United States: New Jersey", + 'US-NM' => "United States: New Mexico", + 'US-NY' => "United States: New York", + 'US-NC' => "United States: North Carolina", + 'US-ND' => "United States: North Dakota", + 'US-MP' => "United States: Northern Mariana Islands, Illes Marianes del Nord", + 'US-OH' => "United States: Ohio", + 'US-OK' => "United States: Oklahoma", + 'US-OR' => "United States: Oregon", + 'US-PA' => "United States: Pennsylvania", + 'US-PR' => "United States: Puerto Rico", + 'US-RI' => "United States: Rhode Island", + 'US-SC' => "United States: South Carolina", + 'US-SD' => "United States: South Dakota", + 'US-TN' => "United States: Tennessee", + 'US-TX' => "United States: Texas", + 'US-UM' => "United States: United States Minor Outlying Islands, Illes Perifèriques Menors dels EUA", + 'US-UT' => "United States: Utah", + 'US-VT' => "United States: Vermont", + 'US-VI' => "United States: Virgin Islands, Illes Verge", + 'US-VA' => "United States: Virginia", + 'US-WA' => "United States: Washington", + 'US-WV' => "United States: West Virginia", + 'US-WI' => "United States: Wisconsin", + 'US-WY' => "United States: Wyoming", + + '--VN' => "", '-VN' => "Vietnam", + 'VN-44' => "Vietnam: An Giang", + 'VN-43' => "Vietnam: Bà Rịa - Vũng Tàu", + 'VN-57' => "Vietnam: Bình Dương", + 'VN-58' => "Vietnam: Bình Phước", + 'VN-40' => "Vietnam: Bình Thuận", + 'VN-31' => "Vietnam: Bình Định", + 'VN-55' => "Vietnam: Bạc Liêu", + 'VN-54' => "Vietnam: Bắc Giang", + 'VN-53' => "Vietnam: Bắc Kạn", + 'VN-56' => "Vietnam: Bắc Ninh", + 'VN-50' => "Vietnam: Bến Tre", + 'VN-04' => "Vietnam: Cao Bằng", + 'VN-59' => "Vietnam: Cà Mau", + 'VN-48' => "Vietnam: Cần Thơ", + 'VN-30' => "Vietnam: Gia Lai", + 'VN-14' => "Vietnam: Hoà Bình", + 'VN-03' => "Vietnam: Hà Giang", + 'VN-63' => "Vietnam: Hà Nam", + 'VN-64' => "Vietnam: Hà Nội, thủ đô", + 'VN-15' => "Vietnam: Hà Tây", + 'VN-23' => "Vietnam: Hà Tỉnh", + 'VN-66' => "Vietnam: Hưng Yên", + 'VN-61' => "Vietnam: Hải Duong", + 'VN-62' => "Vietnam: Hải Phòng, thành phố", + 'VN-73' => "Vietnam: Hậu Giang", + 'VN-65' => "Vietnam: Hồ Chí Minh, thành phố [Sài Gòn]", + 'VN-34' => "Vietnam: Khánh Hòa", + 'VN-47' => "Vietnam: Kiên Giang", + 'VN-28' => "Vietnam: Kon Tum", + 'VN-01' => "Vietnam: Lai Châu", + 'VN-41' => "Vietnam: Long An", + 'VN-02' => "Vietnam: Lào Cai", + 'VN-35' => "Vietnam: Lâm Đồng", + 'VN-09' => "Vietnam: Lạng Sơn", + 'VN-67' => "Vietnam: Nam Định", + 'VN-22' => "Vietnam: Nghệ An", + 'VN-18' => "Vietnam: Ninh Bình", + 'VN-36' => "Vietnam: Ninh Thuận", + 'VN-68' => "Vietnam: Phú Thọ", + 'VN-32' => "Vietnam: Phú Yên", + 'VN-24' => "Vietnam: Quảng Bình", + 'VN-27' => "Vietnam: Quảng Nam", + 'VN-29' => "Vietnam: Quảng Ngãi", + 'VN-13' => "Vietnam: Quảng Ninh", + 'VN-25' => "Vietnam: Quảng Trị", + 'VN-52' => "Vietnam: Sóc Trăng", + 'VN-05' => "Vietnam: Sơn La", + 'VN-21' => "Vietnam: Thanh Hóa", + 'VN-20' => "Vietnam: Thái Bình", + 'VN-69' => "Vietnam: Thái Nguyên", + 'VN-26' => "Vietnam: Thừa Thiên-Huế", + 'VN-46' => "Vietnam: Tiền Giang", + 'VN-51' => "Vietnam: Trà Vinh", + 'VN-07' => "Vietnam: Tuyên Quang", + 'VN-37' => "Vietnam: Tây Ninh", + 'VN-49' => "Vietnam: Vĩnh Long", + 'VN-70' => "Vietnam: Vĩnh Phúc", + 'VN-06' => "Vietnam: Yên Bái", + 'VN-71' => "Vietnam: Điện Biên", + 'VN-60' => "Vietnam: Đà Nẵng, thành phố", + 'VN-33' => "Vietnam: Đắc Lắk", + 'VN-72' => "Vietnam: Đắk Nông", + 'VN-39' => "Vietnam: Đồng Nai", + 'VN-45' => "Vietnam: Đồng Tháp", + ]; + +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/grouplevel.php b/deployed/regularlabs/libraries/regularlabs/fields/grouplevel.php new file mode 100644 index 00000000..d23e7dd1 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/grouplevel.php @@ -0,0 +1,88 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Language\Text as JText; +use Joomla\Registry\Registry; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_GroupLevel extends \RegularLabs\Library\Field +{ + public $type = 'GroupLevel'; + + protected function getInput() + { + $size = (int) $this->get('size'); + $multiple = $this->get('multiple'); + $show_all = $this->get('show_all'); + $use_names = $this->get('use_names'); + + return $this->selectListAjax( + $this->type, $this->name, $this->value, $this->id, + compact('size', 'multiple', 'show_all', 'use_names') + ); + } + + function getAjaxRaw(Registry $attributes) + { + $name = $attributes->get('name', $this->type); + $id = $attributes->get('id', strtolower($name)); + $value = $attributes->get('value', []); + $size = $attributes->get('size'); + $multiple = $attributes->get('multiple'); + + $options = $this->getOptions( + (bool) $attributes->get('show_all'), + (bool) $attributes->get('use_names') + ); + + return $this->selectList($options, $name, $value, $id, $size, $multiple); + } + + protected function getOptions($show_all = false, $use_names = false) + { + $options = $this->getUserGroups($use_names); + + if ($show_all) + { + $option = (object) []; + $option->value = -1; + $option->text = '- ' . JText::_('JALL') . ' -'; + $option->disable = ''; + array_unshift($options, $option); + } + + return $options; + } + + protected function getUserGroups($use_names = false) + { + $value = $use_names ? 'a.title' : 'a.id'; + + $query = $this->db->getQuery(true) + ->select($value . ' as value, a.title as text, a.parent_id AS parent') + ->from('#__usergroups AS a') + ->select('COUNT(DISTINCT b.id) AS level') + ->join('LEFT', '#__usergroups AS b ON a.lft > b.lft AND a.rgt < b.rgt') + ->group('a.id') + ->order('a.lft ASC'); + $this->db->setQuery($query); + + return $this->db->loadObjectList(); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/header.php b/deployed/regularlabs/libraries/regularlabs/fields/header.php new file mode 100644 index 00000000..9f3e3a52 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/header.php @@ -0,0 +1,141 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Application\ApplicationHelper as JApplicationHelper; +use Joomla\CMS\Language\Text as JText; +use RegularLabs\Library\RegEx as RL_RegEx; +use RegularLabs\Library\StringHelper as RL_String; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_Header extends \RegularLabs\Library\Field +{ + public $type = 'Header'; + + protected function getLabel() + { + return ''; + } + + protected function getInput() + { + $title = $this->get('label'); + $description = $this->get('description'); + $xml = $this->get('xml'); + $url = $this->get('url'); + + if ($description) + { + // variables + $v1 = $this->get('var1'); + $v2 = $this->get('var2'); + $v3 = $this->get('var3'); + $v4 = $this->get('var4'); + $v5 = $this->get('var5'); + + $description = RL_String::html_entity_decoder(trim(JText::sprintf($description, $v1, $v2, $v3, $v4, $v5))); + } + + if ($title) + { + $title = JText::_($title); + } + + if ($description) + { + // Replace inline monospace style with rl_code classname + $description = str_replace('span style="font-family:monospace;"', 'span class="rl_code"', $description); + + // 'Break' plugin style tags + $description = str_replace(['{', '['], ['{', '['], $description); + + // Wrap in paragraph (if not already starting with an html tag) + if ($description[0] != '<') + { + $description = '

' . $description . '

'; + } + } + + if ( ! $xml && $this->form->getValue('element')) + { + if ($this->form->getValue('folder')) + { + $xml = 'plugins/' . $this->form->getValue('folder') . '/' . $this->form->getValue('element') . '/' . $this->form->getValue('element') . '.xml'; + } + else + { + $xml = 'administrator/modules/' . $this->form->getValue('element') . '/' . $this->form->getValue('element') . '.xml'; + } + } + + if ($xml) + { + $xml = JApplicationHelper::parseXMLInstallFile(JPATH_SITE . '/' . $xml); + $version = 0; + if ($xml && isset($xml['version'])) + { + $version = $xml['version']; + } + if ($version) + { + if (strpos($version, 'PRO') !== false) + { + $version = str_replace('PRO', '', $version); + $version .= ' [PRO]'; + } + else if (strpos($version, 'FREE') !== false) + { + $version = str_replace('FREE', '', $version); + $version .= ' [FREE]'; + } + if ($title) + { + $title .= ' v'; + } + else + { + $title = JText::_('Version') . ' '; + } + $title .= $version; + } + } + $html = []; + + if ($title) + { + if ($url) + { + $title = '' . $title . ''; + } + $html[] = '

' . RL_String::html_entity_decoder($title) . '

'; + } + + if ($description) + { + $html[] = $description; + } + + if ($url) + { + $html[] = '

' . JText::_('RL_MORE_INFO') . ' >>

'; + } + + return '
' . implode('', $html); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/header_library.php b/deployed/regularlabs/libraries/regularlabs/fields/header_library.php new file mode 100644 index 00000000..31ec6bee --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/header_library.php @@ -0,0 +1,68 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Language\Text as JText; + +require_once __DIR__ . '/header.php'; + +class JFormFieldRL_Header_Library extends JFormFieldRL_Header +{ + protected function getInput() + { + $extensions = [ + 'Add to Menu', + 'Advanced Module Manager', + 'Advanced Template Manager', + 'Articles Anywhere', + 'Articles Field', + 'Better Preview', + 'Better Trash', + 'Cache Cleaner', + 'CDN for Joomla!', + 'Components Anywhere', + 'Conditional Content', + 'Content Templater', + 'DB Replacer', + 'Dummy Content', + 'Email Protector', + 'GeoIP', + 'IP Login', + 'Modals', + 'Modules Anywhere', + 'Quick Index', + 'Regular Labs Extension Manager', + 'ReReplacer', + 'Simple User Notes', + 'Sliders', + 'Snippets', + 'Sourcerer', + 'Tabs', + 'Tooltips', + 'What? Nothing!', + ]; + + $list = '
  • ' . implode('
  • ', $extensions) . '
'; + + $attributes = $this->element->attributes(); + + $warning = ''; + if (isset($attributes['warning'])) + { + $warning = '
' . JText::_($attributes['warning']) . '
'; + } + + $this->element->attributes()['description'] = JText::sprintf($attributes['description'], $warning, $list); + + return parent::getInput(); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/hikashop.php b/deployed/regularlabs/libraries/regularlabs/fields/hikashop.php new file mode 100644 index 00000000..23a1e4e5 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/hikashop.php @@ -0,0 +1,94 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_HikaShop extends \RegularLabs\Library\FieldGroup +{ + public $type = 'HikaShop'; + + protected function getInput() + { + if ($error = $this->missingFilesOrTables(['categories' => 'category', 'products' => 'product'])) + { + return $error; + } + + return $this->getSelectList(); + } + + function getCategories() + { + $query = $this->db->getQuery(true) + ->select('COUNT(*)') + ->from('#__hikashop_category') + ->where('category_published > -1'); + $this->db->setQuery($query); + $total = $this->db->loadResult(); + + if ($total > $this->max_list_count) + { + return -1; + } + + $query->clear() + ->select('c.category_id') + ->from('#__hikashop_category AS c') + ->where('c.category_type = ' . $this->db->quote('root')); + $this->db->setQuery($query); + $root = (int) $this->db->loadResult(); + + $query->clear() + ->select('c.category_id as id, c.category_parent_id AS parent_id, c.category_name AS title, c.category_published as published') + ->from('#__hikashop_category AS c') + ->where('c.category_type = ' . $this->db->quote('product')) + ->where('c.category_published > -1') + ->order('c.category_ordering, c.category_name'); + $this->db->setQuery($query); + $items = $this->db->loadObjectList(); + + return $this->getOptionsTreeByList($items, $root); + } + + function getProducts() + { + $query = $this->db->getQuery(true) + ->select('COUNT(*)') + ->from('#__hikashop_product AS p') + ->where('p.product_published = 1') + ->where('p.product_type = ' . $this->db->quote('main')); + $this->db->setQuery($query); + $total = $this->db->loadResult(); + + if ($total > $this->max_list_count) + { + return -1; + } + + $query->clear('select') + ->select('p.product_id as id, p.product_name AS name, p.product_published AS published, c.category_name AS cat') + ->join('LEFT', '#__hikashop_product_category AS x ON x.product_id = p.product_id') + ->join('INNER', '#__hikashop_category AS c ON c.category_id = x.category_id') + ->group('p.product_id') + ->order('p.product_id'); + $this->db->setQuery($query); + $list = $this->db->loadObjectList(); + + return $this->getOptionsByList($list, ['cat', 'id']); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/hr.php b/deployed/regularlabs/libraries/regularlabs/fields/hr.php new file mode 100644 index 00000000..045c5f3f --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/hr.php @@ -0,0 +1,38 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +use RegularLabs\Library\Document as RL_Document; + +class JFormFieldRL_HR extends JFormField +{ + public $type = 'HR'; + + protected function getLabel() + { + return ''; + } + + protected function getInput() + { + RL_Document::stylesheet('regularlabs/style.min.css'); + + return '
'; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/icons.php b/deployed/regularlabs/libraries/regularlabs/fields/icons.php new file mode 100644 index 00000000..89b5dee8 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/icons.php @@ -0,0 +1,157 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Language\Text as JText; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_Icons extends \RegularLabs\Library\Field +{ + public $type = 'Icons'; + + protected function getInput() + { + $value = $this->value; + if ( ! is_array($value)) + { + $value = explode(',', $value); + } + + $classes = [ + 'reglab icon-contenttemplater', + 'home', + 'user', + 'locked', + 'comments', + 'comments-2', + 'out', + 'plus', + 'pencil', + 'pencil-2', + 'file', + 'file-add', + 'file-remove', + 'copy', + 'folder', + 'folder-2', + 'picture', + 'pictures', + 'list-view', + 'power-cord', + 'cube', + 'puzzle', + 'flag', + 'tools', + 'cogs', + 'cog', + 'equalizer', + 'wrench', + 'brush', + 'eye', + 'star', + 'calendar', + 'calendar-2', + 'help', + 'support', + 'warning', + 'checkmark', + 'mail', + 'mail-2', + 'drawer', + 'drawer-2', + 'box-add', + 'box-remove', + 'search', + 'filter', + 'camera', + 'play', + 'music', + 'grid-view', + 'grid-view-2', + 'menu', + 'thumbs-up', + 'thumbs-down', + 'plus-2', + 'minus-2', + 'key', + 'quote', + 'quote-2', + 'database', + 'location', + 'zoom-in', + 'zoom-out', + 'health', + 'wand', + 'refresh', + 'vcard', + 'clock', + 'compass', + 'address', + 'feed', + 'flag-2', + 'pin', + 'lamp', + 'chart', + 'bars', + 'pie', + 'dashboard', + 'lightning', + 'move', + 'printer', + 'color-palette', + 'camera-2', + 'cart', + 'basket', + 'broadcast', + 'screen', + 'tablet', + 'mobile', + 'users', + 'briefcase', + 'download', + 'upload', + 'bookmark', + 'out-2', + ]; + + $html = []; + + if ($this->get('show_none')) + { + $checked = (in_array('0', $value) ? ' checked="checked"' : ''); + $html[] = '
'; + $html[] = ''; + $html[] = ''; + $html[] = '
'; + } + + foreach ($classes as $i => $class) + { + $id = str_replace(' ', '_', $this->id . $class); + $checked = (in_array($class, $value) ? ' checked="checked"' : ''); + + $html[] = '
'; + $html[] = ''; + $html[] = ''; + $html[] = '
'; + } + + return '
' . implode('', $html) . '
'; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/isinstalled.php b/deployed/regularlabs/libraries/regularlabs/fields/isinstalled.php new file mode 100644 index 00000000..e38a2987 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/isinstalled.php @@ -0,0 +1,40 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use RegularLabs\Library\Extension as RL_Extension; + +jimport('joomla.form.formfield'); + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_IsInstalled extends \RegularLabs\Library\Field +{ + public $type = 'IsInstalled'; + + protected function getLabel() + { + return ''; + } + + protected function getInput() + { + $is_installed = RL_Extension::isInstalled($this->get('extension'), $this->get('extension_type'), $this->get('folder')); + + return ''; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/k2.php b/deployed/regularlabs/libraries/regularlabs/fields/k2.php new file mode 100644 index 00000000..14935a7b --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/k2.php @@ -0,0 +1,116 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +// If controller.php exists, assume this is K2 v3 +defined('RL_K2_VERSION') or define('RL_K2_VERSION', JFile::exists(JPATH_ADMINISTRATOR . '/components/com_k2/controller.php') ? 3 : 2); + +class JFormFieldRL_K2 extends \RegularLabs\Library\FieldGroup +{ + public $type = 'K2'; + + protected function getInput() + { + if ($error = $this->missingFilesOrTables(['categories', 'items', 'tags'])) + { + return $error; + } + + return $this->getSelectList(); + } + + function getCategories() + { + $state_field = RL_K2_VERSION == 3 ? 'state' : 'published'; + + $query = $this->db->getQuery(true) + ->select('COUNT(*)') + ->from('#__k2_categories AS c') + ->where('c.' . $state_field . ' > -1'); + $this->db->setQuery($query); + $total = $this->db->loadResult(); + + if ($total > $this->max_list_count) + { + return -1; + } + + $parent_field = RL_K2_VERSION == 3 ? 'parent_id' : 'parent'; + $title_field = RL_K2_VERSION == 3 ? 'title' : 'name'; + $ordering_field = RL_K2_VERSION == 3 ? 'lft' : 'ordering'; + + $query->clear('select') + ->select('c.id, c.' . $parent_field . ' AS parent_id, c.' . $title_field . ' AS title, c.' . $state_field . ' AS published'); + if ( ! $this->get('getcategories', 1)) + { + $query->where('c.' . $parent_field . ' = 0'); + } + $query->order('c.' . $ordering_field . ', c.' . $title_field); + $this->db->setQuery($query); + $items = $this->db->loadObjectList(); + + return $this->getOptionsTreeByList($items); + } + + function getTags() + { + $state_field = RL_K2_VERSION == 3 ? 'state' : 'published'; + + $query = $this->db->getQuery(true) + ->select('t.name as id, t.name as name') + ->from('#__k2_tags AS t') + ->where('t.' . $state_field . ' = 1') + ->where('t.name != ' . $this->db->quote('')) + ->group('t.name') + ->order('t.name'); + $this->db->setQuery($query); + $list = $this->db->loadObjectList(); + + return $this->getOptionsByList($list); + } + + function getItems() + { + $state_field = RL_K2_VERSION == 3 ? 'state' : 'published'; + + $query = $this->db->getQuery(true) + ->select('COUNT(*)') + ->from('#__k2_items AS i') + ->where('i.' . $state_field . ' > -1'); + $this->db->setQuery($query); + $total = $this->db->loadResult(); + + if ($total > $this->max_list_count) + { + return -1; + } + + $cat_title_field = RL_K2_VERSION == 3 ? 'title' : 'name'; + + $query->clear('select') + ->select('i.id, i.title as name, c.' . $cat_title_field . ' as cat, i.' . $state_field . ' as published') + ->join('LEFT', '#__k2_categories AS c ON c.id = i.catid') + ->group('i.id') + ->order('i.title, i.ordering, i.id'); + $this->db->setQuery($query); + $list = $this->db->loadObjectList(); + + return $this->getOptionsByList($list, ['cat', 'id']); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/key.php b/deployed/regularlabs/libraries/regularlabs/fields/key.php new file mode 100644 index 00000000..02e33073 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/key.php @@ -0,0 +1,81 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Language\Text as JText; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_Key extends \RegularLabs\Library\Field +{ + public $type = 'Key'; + + protected function getInput() + { + $action = $this->get('action', 'Joomla.submitbutton(\'config.save.component.apply\')'); + + $key = trim($this->value); + + if ( ! $key) + { + return '
' + . '' + . '' + . '
'; + } + + $cloak_length = max(0, strlen($key) - 4); + $key = str_repeat('*', $cloak_length) . substr($this->value, $cloak_length); + + $show = 'jQuery(\'#' . $this->id . '\').attr(\'name\', \'' . $this->name . '\');' + . 'jQuery(\'#' . $this->id . '_hidden\').attr(\'name\', \'\');' + . 'jQuery(\'#' . $this->id . '_button\').hide();' + . 'jQuery(\'#' . $this->id . '_field\').show();'; + + $hide = 'jQuery(\'#' . $this->id . '\').attr(\'name\', \'\');' + . 'jQuery(\'#' . $this->id . '_hidden\').attr(\'name\', \'' . $this->name . '\');' + . 'jQuery(\'#' . $this->id . '_field\').hide();' + . 'jQuery(\'#' . $this->id . '_button\').show();'; + + return + '
' . $key . '
' + + . '
' + . '' + . '
' + + . '
' + + . '' + + . ''; + } +} + diff --git a/deployed/regularlabs/libraries/regularlabs/fields/languages.php b/deployed/regularlabs/libraries/regularlabs/fields/languages.php new file mode 100644 index 00000000..45f2eb86 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/languages.php @@ -0,0 +1,79 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\HTML\HTMLHelper as JHtml; +use Joomla\Registry\Registry; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_Languages extends \RegularLabs\Library\Field +{ + public $type = 'Languages'; + + protected function getInput() + { + $size = (int) $this->get('size'); + $multiple = $this->get('multiple'); + + return $this->selectListSimpleAjax( + $this->type, $this->name, $this->value, $this->id, + compact('size', 'multiple') + ); + } + + function getAjaxRaw(Registry $attributes) + { + $name = $attributes->get('name', $this->type); + $id = $attributes->get('id', strtolower($name)); + $value = $attributes->get('value', []); + $size = $attributes->get('size'); + $multiple = $attributes->get('multiple'); + + $options = $this->getLanguages($value); + + return $this->selectListSimple($options, $name, $value, $id, $size, $multiple); + } + + function getLanguages($value) + { + $langs = JHtml::_('contentlanguage.existing'); + + if ( ! is_array($value)) + { + $value = [$value]; + } + + $options = []; + + foreach ($langs as $lang) + { + if (empty($lang->value)) + { + continue; + } + + $options[] = (object) [ + 'value' => $lang->value, + 'text' => $lang->text . ' [' . $lang->value . ']', + 'selected' => in_array($lang->value, $value), + ]; + } + + return $options; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/license.php b/deployed/regularlabs/libraries/regularlabs/fields/license.php new file mode 100644 index 00000000..cbe8103a --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/license.php @@ -0,0 +1,43 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use RegularLabs\Library\License as RL_License; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_License extends \RegularLabs\Library\Field +{ + public $type = 'License'; + + protected function getLabel() + { + return ''; + } + + protected function getInput() + { + $extension = $this->get('extension'); + + if ( ! strlen($extension)) + { + return ''; + } + + return '
' . RL_License::getMessage($extension, true); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/list.php b/deployed/regularlabs/libraries/regularlabs/fields/list.php new file mode 100644 index 00000000..7fb62723 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/list.php @@ -0,0 +1,63 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('JPATH_PLATFORM') or die; + +use Joomla\CMS\HTML\HTMLHelper as JHtml; + +if ( ! class_exists('JFormFieldList')) +{ + require_once JPATH_LIBRARIES . '/joomla/form/fields/list.php'; +} + +class JFormFieldRL_List extends JFormFieldList +{ + protected $type = 'List'; + + protected function getInput() + { + $html = []; + $attr = ''; + + // Initialize some field attributes. + $attr .= ! empty($this->class) ? ' class="' . $this->class . '"' : ''; + $attr .= $this->size ? ' style="width:' . $this->size . 'px"' : ''; + $attr .= $this->multiple ? ' multiple' : ''; + $attr .= $this->required ? ' required aria-required="true"' : ''; + $attr .= $this->autofocus ? ' autofocus' : ''; + + // To avoid user's confusion, readonly="true" should imply disabled="true". + if ((string) $this->readonly == '1' || (string) $this->readonly == 'true' || (string) $this->disabled == '1' || (string) $this->disabled == 'true') + { + $attr .= ' disabled="disabled"'; + } + + // Initialize JavaScript field attributes. + $attr .= $this->onchange ? ' onchange="' . $this->onchange . '"' : ''; + + // Get the field options. + $options = (array) $this->getOptions(); + + if ((string) $this->readonly == '1' || (string) $this->readonly == 'true') + { + // Create a read-only list (no name) with a hidden input to store the value. + $html[] = JHtml::_('select.genericlist', $options, '', trim($attr), 'value', 'text', $this->value, $this->id); + $html[] = ''; + } + else + { + // Create a regular list. + $html[] = JHtml::_('select.genericlist', $options, $this->name, trim($attr), 'value', 'text', $this->value, $this->id); + } + + return implode($html); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/loadlanguage.php b/deployed/regularlabs/libraries/regularlabs/fields/loadlanguage.php new file mode 100644 index 00000000..83e6ab3c --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/loadlanguage.php @@ -0,0 +1,51 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use RegularLabs\Library\Language as RL_Language; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_LoadLanguage extends \RegularLabs\Library\Field +{ + public $type = 'LoadLanguage'; + + protected function getLabel() + { + return ''; + } + + protected function getInput() + { + $extension = $this->get('extension'); + $admin = $this->get('admin', 1); + + self::loadLanguage($extension, $admin); + + return ''; + } + + function loadLanguage($extension, $admin = 1) + { + if ( ! $extension) + { + return; + } + + RL_Language::load($extension, $admin ? JPATH_ADMINISTRATOR : JPATH_SITE); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/menuitems.php b/deployed/regularlabs/libraries/regularlabs/fields/menuitems.php new file mode 100644 index 00000000..eea854a0 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/menuitems.php @@ -0,0 +1,111 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Language\Text as JText; +use Joomla\Registry\Registry; +use RegularLabs\Library\Language as RL_Language; +use RegularLabs\Library\RegEx as RL_RegEx; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_MenuItems extends \RegularLabs\Library\Field +{ + public $type = 'MenuItems'; + + protected function getInput() + { + $size = (int) $this->get('size'); + $multiple = $this->get('multiple', 0); + + return $this->selectListAjax( + $this->type, $this->name, $this->value, $this->id, + compact('size', 'multiple') + ); + } + + function getAjaxRaw(Registry $attributes) + { + $name = $attributes->get('name', $this->type); + $id = $attributes->get('id', strtolower($name)); + $value = $attributes->get('value', []); + $size = $attributes->get('size'); + $multiple = $attributes->get('multiple'); + + $options = $this->getMenuItems(); + + return $this->selectList($options, $name, $value, $id, $size, $multiple); + } + + /** + * Get a list of menu links for one or all menus. + */ + public static function getMenuItems() + { + RL_Language::load('com_modules', JPATH_ADMINISTRATOR); + JLoader::register('MenusHelper', JPATH_ADMINISTRATOR . '/components/com_menus/helpers/menus.php'); + $menuTypes = MenusHelper::getMenuLinks(); + + foreach ($menuTypes as &$type) + { + $type->value = 'type.' . $type->menutype; + $type->text = $type->title; + $type->level = 0; + $type->class = 'hidechildren'; + $type->labelclass = 'nav-header'; + + $rlu[$type->menutype] = &$type; + + foreach ($type->links as &$link) + { + $check1 = RL_RegEx::replace('[^a-z0-9]', '', strtolower($link->text)); + $check2 = RL_RegEx::replace('[^a-z0-9]', '', $link->alias); + + $text = []; + $text[] = $link->text; + + if ($check1 !== $check2) + { + $text[] = '[' . $link->alias . ']'; + } + + if (in_array($link->type, ['separator', 'heading', 'alias', 'url'])) + { + $text[] = '' . JText::_('COM_MODULES_MENU_ITEM_' . strtoupper($link->type)) . ''; + // Don't disable, as you need to be able to select the 'Also on Child Items' option + // $link->disable = 1; + } + + if ($link->published == 0) + { + $text[] = '' . JText::_('JUNPUBLISHED') . ''; + } + + if (JLanguageMultilang::isEnabled() && $link->language != '' && $link->language != '*') + { + $text[] = $link->language_image + ? JHtml::_('image', 'mod_languages/' . $link->language_image . '.gif', $link->language_title, ['title' => $link->language_title], true) + : '' . $link->language_sef . ''; + } + + $link->text = implode(' ', $text); + } + } + + return $menuTypes; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/mijoshop.php b/deployed/regularlabs/libraries/regularlabs/fields/mijoshop.php new file mode 100644 index 00000000..b5bc1c00 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/mijoshop.php @@ -0,0 +1,105 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_MijoShop extends \RegularLabs\Library\FieldGroup +{ + public $type = 'MijoShop'; + public $store_id = 0; + public $language_id = 1; + + protected function getInput() + { + if ($error = $this->missingFilesOrTables(['categories' => 'category', 'products' => 'product'])) + { + return $error; + } + + if ( ! class_exists('MijoShop')) + { + require_once(JPATH_ROOT . '/components/com_mijoshop/mijoshop/mijoshop.php'); + } + + $this->store_id = (int) MijoShop::get('opencart')->get('config')->get('config_store_id'); + $this->language_id = (int) MijoShop::get('opencart')->get('config')->get('config_language_id'); + + return $this->getSelectList(); + } + + function getCategories() + { + $query = $this->db->getQuery(true) + ->select('COUNT(*)') + ->from('#__mijoshop_category AS c') + ->join('INNER', '#__mijoshop_category_description AS cd ON c.category_id = cd.category_id') + ->join('INNER', '#__mijoshop_category_to_store AS cts ON c.category_id = cts.category_id') + ->where('c.status = 1') + ->where('cd.language_id = ' . $this->language_id) + ->where('cts.store_id = ' . $this->store_id) + ->group('c.category_id'); + $this->db->setQuery($query); + $total = $this->db->loadResult(); + + if ($total > $this->max_list_count) + { + return -1; + } + + $query->clear('select') + ->select('c.category_id AS id, c.parent_id, cd.name AS title, c.status AS published') + ->order('c.sort_order, cd.name'); + $this->db->setQuery($query); + $items = $this->db->loadObjectList(); + + return $this->getOptionsTreeByList($items); + } + + function getProducts() + { + $query = $this->db->getQuery(true) + ->select('COUNT(*)') + ->from('#__mijoshop_product AS p') + ->join('INNER', '#__mijoshop_product_description AS pd ON p.product_id = pd.product_id') + ->join('INNER', '#__mijoshop_product_to_store AS pts ON p.product_id = pts.product_id')->where('p.status = 1') + ->where('p.date_available <= NOW()') + ->where('pd.language_id = ' . $this->language_id) + ->group('p.product_id'); + $this->db->setQuery($query); + $total = $this->db->loadResult(); + + if ($total > $this->max_list_count) + { + return -1; + } + + $query->clear('select') + ->select('p.product_id as id, pd.name, p.model as model, cd.name AS cat, p.status AS published') + ->join('LEFT', '#__mijoshop_product_to_category AS ptc ON p.product_id = ptc.product_id') + ->join('LEFT', '#__mijoshop_category_description AS cd ON ptc.category_id = cd.category_id') + ->join('LEFT', '#__mijoshop_category_to_store AS cts ON ptc.category_id = cts.category_id') + ->where('cts.store_id = ' . $this->store_id) + ->where('cd.language_id = ' . $this->language_id) + ->where('cts.store_id = ' . $this->store_id) + ->order('pd.name, p.model'); + $this->db->setQuery($query); + $list = $this->db->loadObjectList(); + + return $this->getOptionsByList($list, ['model', 'cat', 'id']); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/modules.php b/deployed/regularlabs/libraries/regularlabs/fields/modules.php new file mode 100644 index 00000000..841a2a2a --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/modules.php @@ -0,0 +1,144 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\HTML\HTMLHelper as JHtml; +use Joomla\CMS\Language\Text as JText; +use RegularLabs\Library\Form as RL_Form; +use RegularLabs\Library\RegEx as RL_RegEx; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_Modules extends \RegularLabs\Library\Field +{ + public $type = 'Modules'; + + protected function getInput() + { + JHtml::_('behavior.modal', 'a.modal'); + + $size = $this->get('size') ? 'style="width:' . $this->get('size') . 'px"' : ''; + + $multiple = $this->get('multiple'); + $showtype = $this->get('showtype'); + $showid = $this->get('showid'); + $showinput = $this->get('showinput'); + + // load the list of modules + $query = $this->db->getQuery(true) + ->select('m.id, m.title, m.position, m.module, m.published, m.language') + ->from('#__modules AS m') + ->where('m.client_id = 0') + ->where('m.published > -2') + ->order('m.position, m.title, m.ordering, m.id'); + $this->db->setQuery($query); + $modules = $this->db->loadObjectList(); + + // assemble menu items to the array + $options = []; + + $p = 0; + foreach ($modules as $item) + { + if ($p !== $item->position) + { + $pos = $item->position; + if ($pos == '') + { + $pos = ':: ' . JText::_('JNONE') . ' ::'; + } + $options[] = JHtml::_('select.option', '-', '[ ' . $pos . ' ]', 'value', 'text', true); + } + $p = $item->position; + + $item->title = $item->title; + if ($showtype) + { + $item->title .= ' [' . $item->module . ']'; + } + if ($showinput || $showid) + { + $item->title .= ' [' . $item->id . ']'; + } + if ($item->language && $item->language != '*') + { + $item->title .= ' (' . $item->language . ')'; + } + $item->title = RL_Form::prepareSelectItem($item->title, $item->published); + + $options[] = JHtml::_('select.option', $item->id, $item->title); + } + + if ($showinput) + { + array_unshift($options, JHtml::_('select.option', '-', ' ', 'value', 'text', true)); + array_unshift($options, JHtml::_('select.option', '-', '- ' . JText::_('Select Item') . ' -')); + + if ($multiple) + { + $onchange = 'if ( this.value ) { if ( ' . $this->id . '.value ) { ' . $this->id . '.value+=\',\'; } ' . $this->id . '.value+=this.value; } this.value=\'\';'; + } + else + { + $onchange = 'if ( this.value ) { ' . $this->id . '.value=this.value;' . $this->id . '_text.value=this.options[this.selectedIndex].innerHTML.replace( /^((&|&| )nbsp;|-)*/gm, \'\' ).trim(); } this.value=\'\';'; + } + $attribs = 'class="inputbox" onchange="' . $onchange . '"'; + + $html = '
' . "\n"; + if ( ! $multiple) + { + $val_name = $this->value; + if ($this->value) + { + foreach ($modules as $item) + { + if ($item->id == $this->value) + { + $val_name = $item->title; + if ($showtype) + { + $val_name .= ' [' . $item->module . ']'; + } + $val_name .= ' [' . $this->value . ']'; + break; + } + } + } + $html .= ''; + $html .= ''; + } + else + { + $html .= ''; + } + $html .= '' . "\n"; + $html .= JHtml::_('select.genericlist', $options, '', $attribs, 'value', 'text', '', ''); + $html .= '
' . "\n"; + } + else + { + $attr = $size; + $attr .= $multiple ? ' multiple="multiple"' : ''; + $attr .= ' class="input-xxlarge"'; + + $html = JHtml::_('select.genericlist', $options, $this->name, trim($attr), 'value', 'text', $this->value, $this->id); + $html = '
' . $html . '
'; + } + + return RL_RegEx::replace('>\[\[\:(.*?)\:\]\]', ' style="\1">', $html); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/multiselect.php b/deployed/regularlabs/libraries/regularlabs/fields/multiselect.php new file mode 100644 index 00000000..948e9625 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/multiselect.php @@ -0,0 +1,46 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_MultiSelect extends \RegularLabs\Library\Field +{ + public $type = 'MultiSelect'; + + protected function getInput() + { + $this->params = $this->element->attributes(); + + if ( ! is_array($this->value)) + { + $this->value = explode(',', $this->value); + } + + foreach ($this->element->children() as $item) + { + $item_value = (string) $item['value']; + $item_name = JText::_(trim((string) $item)); + $item_disabled = (int) $item['disabled']; + $options[] = JHtml::_('select.option', $item_value, $item_name, 'value', 'text', $item_disabled); + } + + $size = (int) $this->get('size'); + + return $this->selectList($options, $this->name, $this->value, $this->id, $size, true); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/note.php b/deployed/regularlabs/libraries/regularlabs/fields/note.php new file mode 100644 index 00000000..eda5f8c2 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/note.php @@ -0,0 +1,69 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Language\Text as JText; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_Note extends \RegularLabs\Library\Field +{ + public $type = 'Note'; + + public function setup(SimpleXMLElement $element, $value, $group = null) + { + $this->element = $element; + + $element['label'] = $this->prepareText($element['label']); + $element['description'] = $this->prepareText($element['description']); + $element['translateDescription'] = false; + + return parent::setup($element, $value, $group); + } + + protected function getLabel() + { + if (empty($this->element['label']) && empty($this->element['description'])) + { + return ''; + } + + $title = $this->element['label'] ? (string) $this->element['label'] : ($this->element['title'] ? (string) $this->element['title'] : ''); + $heading = $this->element['heading'] ? (string) $this->element['heading'] : 'h4'; + $description = (string) $this->element['description']; + $class = ! empty($this->class) ? ' class="' . $this->class . '"' : ''; + $close = (string) $this->element['close']; + + $html = []; + + if ($close) + { + $close = $close == 'true' ? 'alert' : $close; + $html[] = ''; + } + + $html[] = ! empty($title) ? '<' . $heading . '>' . JText::_($title) . '' : ''; + $html[] = ! empty($description) ? JText::_($description) : ''; + + return '
' . implode('', $html); + } + + protected function getInput() + { + return ''; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/onlypro.php b/deployed/regularlabs/libraries/regularlabs/fields/onlypro.php new file mode 100644 index 00000000..fda5f52c --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/onlypro.php @@ -0,0 +1,108 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use RegularLabs\Library\Extension as RL_Extension; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_OnlyPro extends \RegularLabs\Library\Field +{ + public $type = 'OnlyPro'; + + protected function getLabel() + { + $label = $this->prepareText($this->get('label')); + $tooltip = $this->prepareText($this->get('description')); + + if ( ! $label && ! $tooltip) + { + return '
' . $this->getText(); + } + + if ( ! $label) + { + return $tooltip; + } + + if ( ! $tooltip) + { + return $label; + } + + return ''; + } + + protected function getInput() + { + $label = $this->prepareText($this->get('label')); + $tooltip = $this->prepareText($this->get('description')); + + if ( ! $label && ! $tooltip) + { + return ''; + } + + return $this->getText(); + } + + protected function getText() + { + $text = JText::_('RL_ONLY_AVAILABLE_IN_PRO'); + $text = '' . $text . ''; + + $extension = $this->getExtensionName(); + + $alias = RL_Extension::getAliasByName($extension); + + if ($alias) + { + $text = '' + . $text + . ''; + } + + $class = $this->get('class'); + $class = $class ? ' class="' . $class . '"' : ''; + + return '' . $text . '
'; + } + + protected function getExtensionName() + { + if ($extension = $this->form->getValue('element')) + { + return $extension; + } + + if ($extension = JFactory::getApplication()->input->get('component')) + { + return str_replace('com_', '', $extension); + } + + if ($extension = JFactory::getApplication()->input->get('folder')) + { + $extension = explode('.', $extension); + + return array_pop($extension); + } + + return false; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/password.php b/deployed/regularlabs/libraries/regularlabs/fields/password.php new file mode 100644 index 00000000..8d254a65 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/password.php @@ -0,0 +1,73 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +require_once JPATH_LIBRARIES . '/joomla/form/fields/password.php'; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +use RegularLabs\Library\StringHelper as RL_String; + +class JFormFieldRL_Password extends JFormFieldPassword +{ + public $type = 'Password'; + + public function setup(SimpleXMLElement $element, $value, $group = null) + { + $this->element = $element; + + $element['label'] = $this->prepareText($element['label']); + $element['description'] = $this->prepareText($element['description']); + $element['translateDescription'] = false; + + return parent::setup($element, $value, $group); + } + + private function prepareText($string = '') + { + $string = trim($string); + + if ($string == '') + { + return ''; + } + + // variables + $var1 = JText::_($this->get('var1')); + $var2 = JText::_($this->get('var2')); + $var3 = JText::_($this->get('var3')); + $var4 = JText::_($this->get('var4')); + $var5 = JText::_($this->get('var5')); + + $string = JText::sprintf(JText::_($string), $var1, $var2, $var3, $var4, $var5); + $string = trim(RL_String::html_entity_decoder($string)); + $string = str_replace('"', '"', $string); + $string = str_replace('span style="font-family:monospace;"', 'span class="rl_code"', $string); + + return $string; + } + + private function get($val, $default = '') + { + if ( ! isset($this->params[$val]) || (string) $this->params[$val] == '') + { + return $default; + } + + return (string) $this->params[$val]; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/plaintext.php b/deployed/regularlabs/libraries/regularlabs/fields/plaintext.php new file mode 100644 index 00000000..64680f80 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/plaintext.php @@ -0,0 +1,60 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_PlainText extends \RegularLabs\Library\Field +{ + public $type = 'PlainText'; + + protected function getLabel() + { + $label = $this->prepareText($this->get('label')); + $tooltip = $this->prepareText($this->get('description')); + + if ( ! $label && ! $tooltip) + { + return ''; + } + + if ( ! $label) + { + return '
' . $tooltip . '
'; + } + + if ( ! $tooltip) + { + return '
' . $label . '
'; + } + + return ''; + } + + protected function getInput() + { + $text = $this->prepareText($this->value); + + if ( ! $text) + { + return ''; + } + + return '
' . $text . '
'; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/radioimages.php b/deployed/regularlabs/libraries/regularlabs/fields/radioimages.php new file mode 100644 index 00000000..6ed3cc86 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/radioimages.php @@ -0,0 +1,92 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +use RegularLabs\Library\RegEx as RL_RegEx; + +class JFormFieldRL_RadioImages extends \RegularLabs\Library\Field +{ + public $type = 'RadioImages'; + + protected function getInput() + { + $this->params = $this->element->attributes(); + + jimport('joomla.filesystem.folder'); + jimport('joomla.filesystem.file'); + + // path to images directory + $path = JPATH_ROOT . '/' . $this->get('directory'); + $filter = $this->get('filter'); + $exclude = $this->get('exclude'); + $stripExt = $this->get('stripext'); + $files = JFolder::files($path, $filter); + $rowcount = $this->get('rowcount'); + + $options = []; + + if ( ! $this->get('hide_none')) + { + $options[] = JHtml::_('select.option', '-1', JText::_('Do not use') . '
'); + } + + if ( ! $this->get('hide_default')) + { + $options[] = JHtml::_('select.option', '', JText::_('Use default') . '
'); + } + + if (is_array($files)) + { + $count = 0; + foreach ($files as $file) + { + if ($exclude) + { + if (RL_RegEx::match(chr(1) . $exclude . chr(1), $file)) + { + continue; + } + } + $count++; + if ($stripExt) + { + $file = JFile::stripExt($file); + } + $image = '' . $file . ''; + if ($rowcount && $count >= $rowcount) + { + $image .= '
'; + $count = 0; + } + $options[] = JHtml::_('select.option', $file, $image); + } + } + + $list = JHtml::_('select.radiolist', $options, '' . $this->name . '', '', 'value', 'text', $this->value, $this->id); + + $list = '
' . str_replace('
'; + $list = str_replace([''], [''], $list); + $list = RL_RegEx::replace('(\s*)
', '
\1', $list); + $list = str_replace('
', '
', $list); + + $list = '
' . $list; + + return $list; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/redshop.php b/deployed/regularlabs/libraries/regularlabs/fields/redshop.php new file mode 100644 index 00000000..ca20879f --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/redshop.php @@ -0,0 +1,126 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use RegularLabs\Library\DB as RL_DB; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_RedShop extends \RegularLabs\Library\FieldGroup +{ + public $type = 'RedShop'; + + protected function getInput() + { + if ($error = $this->missingFilesOrTables(['categories' => 'category', 'products' => 'product'])) + { + return $error; + } + + return $this->getSelectList(); + } + + function getCategories() + { + $query = $this->db->getQuery(true) + ->select('COUNT(*)') + ->from('#__redshop_category AS c') + ->where('c.published > -1'); + $this->db->setQuery($query); + $total = $this->db->loadResult(); + + if ($total > $this->max_list_count) + { + return -1; + } + + $this->db->setQuery($this->getCategoriesQuery()); + $items = $this->db->loadObjectList(); + + return $this->getOptionsTreeByList($items); + } + + function getProducts() + { + $query = $this->db->getQuery(true) + ->select('COUNT(*)') + ->from('#__redshop_product AS p') + ->where('p.published > -1'); + $this->db->setQuery($query); + $total = $this->db->loadResult(); + + if ($total > $this->max_list_count) + { + return -1; + } + + $this->db->setQuery($this->getProductsQuery()); + $list = $this->db->loadObjectList(); + + return $this->getOptionsByList($list, ['number', 'cat']); + } + + private function getCategoriesQuery() + { + $query = $this->db->getQuery(true) + ->select('c.id, c.parent_id, c.name AS title, c.published') + ->from('#__redshop_category AS c') + ->where('c.published > -1'); + + if (RL_DB::tableExists('redshop_category_xref')) + { + $query->clear('select') + ->select('c.category_id as id, x.category_parent_id AS parent_id, c.category_name AS title, c.published') + ->join('LEFT', '#__redshop_category_xref AS x ON x.category_child_id = c.category_id') + ->group('c.category_id') + ->order('c.ordering, c.category_name'); + + return $query; + } + + $query + ->group('c.id') + ->order('c.ordering, c.name'); + + return $query; + } + + private function getProductsQuery() + { + $query = $this->db->getQuery(true) + ->select('p.product_id as id, p.product_name AS name, p.product_number as number, c.name AS cat, p.published') + ->from('#__redshop_product AS p') + ->where('p.published > -1') + ->join('LEFT', '#__redshop_product_category_xref AS x ON x.product_id = p.product_id') + ->group('p.product_id') + ->order('p.product_name, p.product_number'); + + if (RL_DB::tableExists('redshop_category_xref')) + { + $query->clear('select') + ->select('p.product_id as id, p.product_name AS name, p.product_number as number, c.category_name AS cat, p.published') + ->join('LEFT', '#__redshop_category AS c ON c.category_id = x.category_id'); + + return $query; + } + + $query + ->join('LEFT', '#__redshop_category AS c ON c.id = x.category_id'); + + return $query; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/regions.txt b/deployed/regularlabs/libraries/regularlabs/fields/regions.txt new file mode 100644 index 00000000..227df1ec --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/regions.txt @@ -0,0 +1,4573 @@ +// Region codes taken from https://documentation.snoobi.com/region-codes + +'--AF' => '','-AF' => 'Afghanistan', +'AF-01' => 'Afghanistan: Badakhshan', +'AF-02' => 'Afghanistan: Badghis', +'AF-03' => 'Afghanistan: Baghlan', +'AF-30' => 'Afghanistan: Balkh', +'AF-05' => 'Afghanistan: Bamian', +'AF-06' => 'Afghanistan: Farah', +'AF-07' => 'Afghanistan: Faryab', +'AF-08' => 'Afghanistan: Ghazni', +'AF-09' => 'Afghanistan: Ghowr', +'AF-10' => 'Afghanistan: Helmand', +'AF-11' => 'Afghanistan: Herat', +'AF-31' => 'Afghanistan: Jowzjan', +'AF-13' => 'Afghanistan: Kabol', +'AF-23' => 'Afghanistan: Kandahar', +'AF-14' => 'Afghanistan: Kapisa', +'AF-37' => 'Afghanistan: Khowst', +'AF-15' => 'Afghanistan: Konar', +'AF-34' => 'Afghanistan: Konar', +'AF-24' => 'Afghanistan: Kondoz', +'AF-16' => 'Afghanistan: Laghman', +'AF-35' => 'Afghanistan: Laghman', +'AF-17' => 'Afghanistan: Lowgar', +'AF-18' => 'Afghanistan: Nangarhar', +'AF-19' => 'Afghanistan: Nimruz', +'AF-38' => 'Afghanistan: Nurestan', +'AF-20' => 'Afghanistan: Oruzgan', +'AF-21' => 'Afghanistan: Paktia', +'AF-36' => 'Afghanistan: Paktia', +'AF-29' => 'Afghanistan: Paktika', +'AF-22' => 'Afghanistan: Parvan', +'AF-32' => 'Afghanistan: Samangan', +'AF-33' => 'Afghanistan: Sar-e Pol', +'AF-26' => 'Afghanistan: Takhar', +'AF-27' => 'Afghanistan: Vardak', +'AF-28' => 'Afghanistan: Zabol', + +'--AL' => '','-AL' => 'Albania', +'AL-40' => 'Albania: Berat', +'AL-41' => 'Albania: Diber', +'AL-42' => 'Albania: Durres', +'AL-43' => 'Albania: Elbasan', +'AL-44' => 'Albania: Fier', +'AL-45' => 'Albania: Gjirokaster', +'AL-46' => 'Albania: Korce', +'AL-47' => 'Albania: Kukes', +'AL-48' => 'Albania: Lezhe', +'AL-49' => 'Albania: Shkoder', +'AL-50' => 'Albania: Tirane', +'AL-51' => 'Albania: Vlore', + +'--DZ' => '','-DZ' => 'Algeria', +'DZ-34' => 'Algeria: Adrar', +'DZ-35' => 'Algeria: Ain Defla', +'DZ-36' => 'Algeria: Ain Temouchent', +'DZ-01' => 'Algeria: Alger', +'DZ-37' => 'Algeria: Annaba', +'DZ-03' => 'Algeria: Batna', +'DZ-38' => 'Algeria: Bechar', +'DZ-18' => 'Algeria: Bejaia', +'DZ-19' => 'Algeria: Biskra', +'DZ-20' => 'Algeria: Blida', +'DZ-39' => 'Algeria: Bordj Bou Arreridj', +'DZ-21' => 'Algeria: Bouira', +'DZ-40' => 'Algeria: Boumerdes', +'DZ-41' => 'Algeria: Chlef', +'DZ-04' => 'Algeria: Constantine', +'DZ-22' => 'Algeria: Djelfa', +'DZ-42' => 'Algeria: El Bayadh', +'DZ-43' => 'Algeria: El Oued', +'DZ-44' => 'Algeria: El Tarf', +'DZ-45' => 'Algeria: Ghardaia', +'DZ-23' => 'Algeria: Guelma', +'DZ-46' => 'Algeria: Illizi', +'DZ-24' => 'Algeria: Jijel', +'DZ-47' => 'Algeria: Khenchela', +'DZ-25' => 'Algeria: Laghouat', +'DZ-26' => 'Algeria: Mascara', +'DZ-06' => 'Algeria: Medea', +'DZ-48' => 'Algeria: Mila', +'DZ-07' => 'Algeria: Mostaganem', +'DZ-27' => 'Algeria: M\'sila', +'DZ-49' => 'Algeria: Naama', +'DZ-09' => 'Algeria: Oran', +'DZ-50' => 'Algeria: Ouargla', +'DZ-29' => 'Algeria: Oum el Bouaghi', +'DZ-51' => 'Algeria: Relizane', +'DZ-10' => 'Algeria: Saida', +'DZ-12' => 'Algeria: Setif', +'DZ-30' => 'Algeria: Sidi Bel Abbes', +'DZ-31' => 'Algeria: Skikda', +'DZ-52' => 'Algeria: Souk Ahras', +'DZ-53' => 'Algeria: Tamanghasset', +'DZ-33' => 'Algeria: Tebessa', +'DZ-13' => 'Algeria: Tiaret', +'DZ-54' => 'Algeria: Tindouf', +'DZ-55' => 'Algeria: Tipaza', +'DZ-56' => 'Algeria: Tissemsilt', +'DZ-14' => 'Algeria: Tizi Ouzou', +'DZ-15' => 'Algeria: Tlemcen', + +'--AD' => '','-AD' => 'Andorra', +'AD-07' => 'Andorra: Andorra la Vella', +'AD-02' => 'Andorra: Canillo', +'AD-03' => 'Andorra: Encamp', +'AD-08' => 'Andorra: Escaldes-Engordany', +'AD-04' => 'Andorra: La Massana', +'AD-05' => 'Andorra: Ordino', +'AD-06' => 'Andorra: Sant Julia de Loria', + +'--AO' => '','-AO' => 'Angola', +'AO-19' => 'Angola: Bengo', +'AO-01' => 'Angola: Benguela', +'AO-02' => 'Angola: Bie', +'AO-03' => 'Angola: Cabinda', +'AO-04' => 'Angola: Cuando Cubango', +'AO-05' => 'Angola: Cuanza Norte', +'AO-06' => 'Angola: Cuanza Sul', +'AO-07' => 'Angola: Cunene', +'AO-08' => 'Angola: Huambo', +'AO-09' => 'Angola: Huila', +'AO-20' => 'Angola: Luanda', +'AO-17' => 'Angola: Lunda Norte', +'AO-18' => 'Angola: Lunda Sul', +'AO-12' => 'Angola: Malanje', +'AO-14' => 'Angola: Moxico', +'AO-15' => 'Angola: Uige', +'AO-16' => 'Angola: Zaire', + +'--AG' => '','-AG' => 'Antigua and Barbuda', +'AG-01' => 'Antigua and Barbuda: Barbuda', +'AG-03' => 'Antigua and Barbuda: Saint George', +'AG-04' => 'Antigua and Barbuda: Saint John', +'AG-05' => 'Antigua and Barbuda: Saint Mary', +'AG-06' => 'Antigua and Barbuda: Saint Paul', +'AG-07' => 'Antigua and Barbuda: Saint Peter', +'AG-08' => 'Antigua and Barbuda: Saint Philip', + +'--AR' => '','-AR' => 'Argentina', +'AR-01' => 'Argentina: Buenos Aires', +'AR-02' => 'Argentina: Catamarca', +'AR-03' => 'Argentina: Chaco', +'AR-04' => 'Argentina: Chubut', +'AR-05' => 'Argentina: Cordoba', +'AR-06' => 'Argentina: Corrientes', +'AR-07' => 'Argentina: Distrito Federal', +'AR-08' => 'Argentina: Entre Rios', +'AR-09' => 'Argentina: Formosa', +'AR-10' => 'Argentina: Jujuy', +'AR-11' => 'Argentina: La Pampa', +'AR-12' => 'Argentina: La Rioja', +'AR-13' => 'Argentina: Mendoza', +'AR-14' => 'Argentina: Misiones', +'AR-15' => 'Argentina: Neuquen', +'AR-16' => 'Argentina: Rio Negro', +'AR-17' => 'Argentina: Salta', +'AR-18' => 'Argentina: San Juan', +'AR-19' => 'Argentina: San Luis', +'AR-20' => 'Argentina: Santa Cruz', +'AR-21' => 'Argentina: Santa Fe', +'AR-22' => 'Argentina: Santiago del Estero', +'AR-23' => 'Argentina: Tierra del Fuego', +'AR-24' => 'Argentina: Tucuman', + +'--AM' => '','-AM' => 'Armenia', +'AM-01' => 'Armenia: Aragatsotn', +'AM-02' => 'Armenia: Ararat', +'AM-03' => 'Armenia: Armavir', +'AM-04' => 'Armenia: Geghark\'unik\'', +'AM-05' => 'Armenia: Kotayk\'', +'AM-06' => 'Armenia: Lorri', +'AM-07' => 'Armenia: Shirak', +'AM-08' => 'Armenia: Syunik\'', +'AM-09' => 'Armenia: Tavush', +'AM-10' => 'Armenia: Vayots\' Dzor', +'AM-11' => 'Armenia: Yerevan', + +'--AU' => '','-AU' => 'Australia', +'AU-01' => 'Australia: Australian Capital Territory', +'AU-02' => 'Australia: New South Wales', +'AU-03' => 'Australia: Northern Territory', +'AU-04' => 'Australia: Queensland', +'AU-05' => 'Australia: South Australia', +'AU-06' => 'Australia: Tasmania', +'AU-07' => 'Australia: Victoria', +'AU-08' => 'Australia: Western Australia', + +'--AT' => '','-AT' => 'Austria', +'AT-01' => 'Austria: Burgenland', +'AT-02' => 'Austria: Karnten', +'AT-03' => 'Austria: Niederosterreich', +'AT-04' => 'Austria: Oberosterreich', +'AT-05' => 'Austria: Salzburg', +'AT-06' => 'Austria: Steiermark', +'AT-07' => 'Austria: Tirol', +'AT-08' => 'Austria: Vorarlberg', +'AT-09' => 'Austria: Wien', + +'--AZ' => '','-AZ' => 'Azerbaijan', +'AZ-01' => 'Azerbaijan: Abseron', +'AZ-02' => 'Azerbaijan: Agcabadi', +'AZ-03' => 'Azerbaijan: Agdam', +'AZ-04' => 'Azerbaijan: Agdas', +'AZ-05' => 'Azerbaijan: Agstafa', +'AZ-06' => 'Azerbaijan: Agsu', +'AZ-07' => 'Azerbaijan: Ali Bayramli', +'AZ-08' => 'Azerbaijan: Astara', +'AZ-09' => 'Azerbaijan: Baki', +'AZ-10' => 'Azerbaijan: Balakan', +'AZ-11' => 'Azerbaijan: Barda', +'AZ-12' => 'Azerbaijan: Beylaqan', +'AZ-13' => 'Azerbaijan: Bilasuvar', +'AZ-14' => 'Azerbaijan: Cabrayil', +'AZ-15' => 'Azerbaijan: Calilabad', +'AZ-16' => 'Azerbaijan: Daskasan', +'AZ-17' => 'Azerbaijan: Davaci', +'AZ-18' => 'Azerbaijan: Fuzuli', +'AZ-19' => 'Azerbaijan: Gadabay', +'AZ-20' => 'Azerbaijan: Ganca', +'AZ-21' => 'Azerbaijan: Goranboy', +'AZ-22' => 'Azerbaijan: Goycay', +'AZ-23' => 'Azerbaijan: Haciqabul', +'AZ-24' => 'Azerbaijan: Imisli', +'AZ-25' => 'Azerbaijan: Ismayilli', +'AZ-26' => 'Azerbaijan: Kalbacar', +'AZ-27' => 'Azerbaijan: Kurdamir', +'AZ-28' => 'Azerbaijan: Lacin', +'AZ-29' => 'Azerbaijan: Lankaran', +'AZ-30' => 'Azerbaijan: Lankaran', +'AZ-31' => 'Azerbaijan: Lerik', +'AZ-32' => 'Azerbaijan: Masalli', +'AZ-33' => 'Azerbaijan: Mingacevir', +'AZ-34' => 'Azerbaijan: Naftalan', +'AZ-35' => 'Azerbaijan: Naxcivan', +'AZ-36' => 'Azerbaijan: Neftcala', +'AZ-37' => 'Azerbaijan: Oguz', +'AZ-38' => 'Azerbaijan: Qabala', +'AZ-39' => 'Azerbaijan: Qax', +'AZ-40' => 'Azerbaijan: Qazax', +'AZ-41' => 'Azerbaijan: Qobustan', +'AZ-42' => 'Azerbaijan: Quba', +'AZ-43' => 'Azerbaijan: Qubadli', +'AZ-44' => 'Azerbaijan: Qusar', +'AZ-45' => 'Azerbaijan: Saatli', +'AZ-46' => 'Azerbaijan: Sabirabad', +'AZ-47' => 'Azerbaijan: Saki', +'AZ-48' => 'Azerbaijan: Saki', +'AZ-49' => 'Azerbaijan: Salyan', +'AZ-50' => 'Azerbaijan: Samaxi', +'AZ-51' => 'Azerbaijan: Samkir', +'AZ-52' => 'Azerbaijan: Samux', +'AZ-53' => 'Azerbaijan: Siyazan', +'AZ-54' => 'Azerbaijan: Sumqayit', +'AZ-55' => 'Azerbaijan: Susa', +'AZ-56' => 'Azerbaijan: Susa', +'AZ-57' => 'Azerbaijan: Tartar', +'AZ-58' => 'Azerbaijan: Tovuz', +'AZ-59' => 'Azerbaijan: Ucar', +'AZ-60' => 'Azerbaijan: Xacmaz', +'AZ-61' => 'Azerbaijan: Xankandi', +'AZ-62' => 'Azerbaijan: Xanlar', +'AZ-63' => 'Azerbaijan: Xizi', +'AZ-64' => 'Azerbaijan: Xocali', +'AZ-65' => 'Azerbaijan: Xocavand', +'AZ-66' => 'Azerbaijan: Yardimli', +'AZ-67' => 'Azerbaijan: Yevlax', +'AZ-68' => 'Azerbaijan: Yevlax', +'AZ-69' => 'Azerbaijan: Zangilan', +'AZ-70' => 'Azerbaijan: Zaqatala', +'AZ-71' => 'Azerbaijan: Zardab', + +'--BS' => '','-BS' => 'Bahamas', +'BS-24' => 'Bahamas: Acklins and Crooked Islands', +'BS-05' => 'Bahamas: Bimini', +'BS-06' => 'Bahamas: Cat Island', +'BS-10' => 'Bahamas: Exuma', +'BS-25' => 'Bahamas: Freeport', +'BS-26' => 'Bahamas: Fresh Creek', +'BS-27' => 'Bahamas: Governor\'s Harbour', +'BS-28' => 'Bahamas: Green Turtle Cay', +'BS-22' => 'Bahamas: Harbour Island', +'BS-29' => 'Bahamas: High Rock', +'BS-13' => 'Bahamas: Inagua', +'BS-30' => 'Bahamas: Kemps Bay', +'BS-15' => 'Bahamas: Long Island', +'BS-31' => 'Bahamas: Marsh Harbour', +'BS-16' => 'Bahamas: Mayaguana', +'BS-23' => 'Bahamas: New Providence', +'BS-32' => 'Bahamas: Nichollstown and Berry Islands', +'BS-18' => 'Bahamas: Ragged Island', +'BS-33' => 'Bahamas: Rock Sound', +'BS-35' => 'Bahamas: San Salvador and Rum Cay', +'BS-34' => 'Bahamas: Sandy Point', + +'--BH' => '','-BH' => 'Bahrain', +'BH-01' => 'Bahrain: Al Hadd', +'BH-02' => 'Bahrain: Al Manamah', +'BH-08' => 'Bahrain: Al Mintaqah al Gharbiyah', +'BH-11' => 'Bahrain: Al Mintaqah al Wusta', +'BH-10' => 'Bahrain: Al Mintaqah ash Shamaliyah', +'BH-03' => 'Bahrain: Al Muharraq', +'BH-13' => 'Bahrain: Ar Rifa', +'BH-05' => 'Bahrain: Jidd Hafs', +'BH-14' => 'Bahrain: Madinat Hamad', +'BH-12' => 'Bahrain: Madinat', +'BH-09' => 'Bahrain: Mintaqat Juzur Hawar', +'BH-06' => 'Bahrain: Sitrah', + +'--BD' => '','-BD' => 'Bangladesh', +'BD-22' => 'Bangladesh: Bagerhat', +'BD-04' => 'Bangladesh: Bandarban', +'BD-25' => 'Bangladesh: Barguna', +'BD-01' => 'Bangladesh: Barisal', +'BD-23' => 'Bangladesh: Bhola', +'BD-24' => 'Bangladesh: Bogra', +'BD-26' => 'Bangladesh: Brahmanbaria', +'BD-27' => 'Bangladesh: Chandpur', +'BD-28' => 'Bangladesh: Chapai Nawabganj', +'BD-29' => 'Bangladesh: Chattagram', +'BD-30' => 'Bangladesh: Chuadanga', +'BD-05' => 'Bangladesh: Comilla', +'BD-31' => 'Bangladesh: Cox\'s Bazar', +'BD-32' => 'Bangladesh: Dhaka', +'BD-33' => 'Bangladesh: Dinajpur', +'BD-34' => 'Bangladesh: Faridpur', +'BD-35' => 'Bangladesh: Feni', +'BD-36' => 'Bangladesh: Gaibandha', +'BD-37' => 'Bangladesh: Gazipur', +'BD-38' => 'Bangladesh: Gopalganj', +'BD-39' => 'Bangladesh: Habiganj', +'BD-40' => 'Bangladesh: Jaipurhat', +'BD-41' => 'Bangladesh: Jamalpur', +'BD-42' => 'Bangladesh: Jessore', +'BD-43' => 'Bangladesh: Jhalakati', +'BD-44' => 'Bangladesh: Jhenaidah', +'BD-45' => 'Bangladesh: Khagrachari', +'BD-46' => 'Bangladesh: Khulna', +'BD-47' => 'Bangladesh: Kishorganj', +'BD-48' => 'Bangladesh: Kurigram', +'BD-49' => 'Bangladesh: Kushtia', +'BD-50' => 'Bangladesh: Laksmipur', +'BD-51' => 'Bangladesh: Lalmonirhat', +'BD-52' => 'Bangladesh: Madaripur', +'BD-53' => 'Bangladesh: Magura', +'BD-54' => 'Bangladesh: Manikganj', +'BD-55' => 'Bangladesh: Meherpur', +'BD-56' => 'Bangladesh: Moulavibazar', +'BD-57' => 'Bangladesh: Munshiganj', +'BD-12' => 'Bangladesh: Mymensingh', +'BD-58' => 'Bangladesh: Naogaon', +'BD-59' => 'Bangladesh: Narail', +'BD-60' => 'Bangladesh: Narayanganj', +'BD-61' => 'Bangladesh: Narsingdi', +'BD-62' => 'Bangladesh: Nator', +'BD-63' => 'Bangladesh: Netrakona', +'BD-64' => 'Bangladesh: Nilphamari', +'BD-13' => 'Bangladesh: Noakhali', +'BD-65' => 'Bangladesh: Pabna', +'BD-66' => 'Bangladesh: Panchagar', +'BD-67' => 'Bangladesh: Parbattya Chattagram', +'BD-15' => 'Bangladesh: Patuakhali', +'BD-68' => 'Bangladesh: Pirojpur', +'BD-69' => 'Bangladesh: Rajbari', +'BD-70' => 'Bangladesh: Rajshahi', +'BD-71' => 'Bangladesh: Rangpur', +'BD-72' => 'Bangladesh: Satkhira', +'BD-73' => 'Bangladesh: Shariyatpur', +'BD-74' => 'Bangladesh: Sherpur', +'BD-75' => 'Bangladesh: Sirajganj', +'BD-76' => 'Bangladesh: Sunamganj', +'BD-77' => 'Bangladesh: Sylhet', +'BD-78' => 'Bangladesh: Tangail', +'BD-79' => 'Bangladesh: Thakurgaon', + +'--BB' => '','-BB' => 'Barbados', +'BB-01' => 'Barbados: Christ Church', +'BB-02' => 'Barbados: Saint Andrew', +'BB-03' => 'Barbados: Saint George', +'BB-04' => 'Barbados: Saint James', +'BB-05' => 'Barbados: Saint John', +'BB-06' => 'Barbados: Saint Joseph', +'BB-07' => 'Barbados: Saint Lucy', +'BB-08' => 'Barbados: Saint Michael', +'BB-09' => 'Barbados: Saint Peter', +'BB-10' => 'Barbados: Saint Philip', +'BB-11' => 'Barbados: Saint Thomas', + +'--BY' => '','-BY' => 'Belarus', +'BY-01' => 'Belarus: Brestskaya Voblasts\'', +'BY-02' => 'Belarus: Homyel\'skaya Voblasts\'', +'BY-03' => 'Belarus: Hrodzyenskaya Voblasts\'', +'BY-06' => 'Belarus: Mahilyowskaya Voblasts\'', +'BY-04' => 'Belarus: Minsk', +'BY-05' => 'Belarus: Minskaya Voblasts\'', +'BY-07' => 'Belarus: Vitsyebskaya Voblasts\'', + +'--BE' => '','-BE' => 'Belgium', +'BE-01' => 'Belgium: Antwerpen', +'BE-10' => 'Belgium: Brabant Wallon', +'BE-02' => 'Belgium: Brabant', +'BE-11' => 'Belgium: Brussels Hoofdstedelijk Gewest', +'BE-03' => 'Belgium: Hainaut', +'BE-04' => 'Belgium: Liege', +'BE-05' => 'Belgium: Limburg', +'BE-06' => 'Belgium: Luxembourg', +'BE-07' => 'Belgium: Namur', +'BE-08' => 'Belgium: Oost-Vlaanderen', +'BE-12' => 'Belgium: Vlaams-Brabant', +'BE-09' => 'Belgium: West-Vlaanderen', + +'--BZ' => '','-BZ' => 'Belize', +'BZ-01' => 'Belize: Belize', +'BZ-02' => 'Belize: Cayo', +'BZ-03' => 'Belize: Corozal', +'BZ-04' => 'Belize: Orange Walk', +'BZ-05' => 'Belize: Stann Creek', +'BZ-06' => 'Belize: Toledo', + +'--BJ' => '','-BJ' => 'Benin', +'BJ-01' => 'Benin: Atakora', +'BJ-02' => 'Benin: Atlantique', +'BJ-03' => 'Benin: Borgou', +'BJ-04' => 'Benin: Mono', +'BJ-05' => 'Benin: Oueme', +'BJ-06' => 'Benin: Zou', + +'--BM' => '','-BM' => 'Bermuda', +'BM-01' => 'Bermuda: Devonshire', +'BM-02' => 'Bermuda: Hamilton', +'BM-03' => 'Bermuda: Hamilton', +'BM-04' => 'Bermuda: Paget', +'BM-05' => 'Bermuda: Pembroke', +'BM-06' => 'Bermuda: Saint George', +'BM-07' => 'Bermuda: Saint George\'s', +'BM-08' => 'Bermuda: Sandys', +'BM-09' => 'Bermuda: Smiths', +'BM-10' => 'Bermuda: Southampton', +'BM-11' => 'Bermuda: Warwick', + +'--BT' => '','-BT' => 'Bhutan', +'BT-05' => 'Bhutan: Bumthang', +'BT-06' => 'Bhutan: Chhukha', +'BT-07' => 'Bhutan: Chirang', +'BT-08' => 'Bhutan: Daga', +'BT-09' => 'Bhutan: Geylegphug', +'BT-10' => 'Bhutan: Ha', +'BT-11' => 'Bhutan: Lhuntshi', +'BT-12' => 'Bhutan: Mongar', +'BT-13' => 'Bhutan: Paro', +'BT-14' => 'Bhutan: Pemagatsel', +'BT-15' => 'Bhutan: Punakha', +'BT-16' => 'Bhutan: Samchi', +'BT-17' => 'Bhutan: Samdrup', +'BT-18' => 'Bhutan: Shemgang', +'BT-19' => 'Bhutan: Tashigang', +'BT-20' => 'Bhutan: Thimphu', +'BT-21' => 'Bhutan: Tongsa', +'BT-22' => 'Bhutan: Wangdi Phodrang', + +'--BO' => '','-BO' => 'Bolivia', +'BO-01' => 'Bolivia: Chuquisaca', +'BO-02' => 'Bolivia: Cochabamba', +'BO-03' => 'Bolivia: El Beni', +'BO-04' => 'Bolivia: La Paz', +'BO-05' => 'Bolivia: Oruro', +'BO-06' => 'Bolivia: Pando', +'BO-07' => 'Bolivia: Potosi', +'BO-08' => 'Bolivia: Santa Cruz', +'BO-09' => 'Bolivia: Tarija', + +'--BA' => '','-BA' => 'Bosnia and Herzegovina', +'BA-01' => 'Bosnia and Herzegovina: Federation of Bosnia and Herzegovina', +'BA-02' => 'Bosnia and Herzegovina: Republika Srpska', + +'--BW' => '','-BW' => 'Botswana', +'BW-01' => 'Botswana: Central', +'BW-02' => 'Botswana: Chobe', +'BW-03' => 'Botswana: Ghanzi', +'BW-04' => 'Botswana: Kgalagadi', +'BW-05' => 'Botswana: Kgatleng', +'BW-06' => 'Botswana: Kweneng', +'BW-07' => 'Botswana: Ngamiland', +'BW-08' => 'Botswana: North-East', +'BW-09' => 'Botswana: South-East', +'BW-10' => 'Botswana: Southern', + +'--BR' => '','-BR' => 'Brazil', +'BR-01' => 'Brazil: Acre', +'BR-02' => 'Brazil: Alagoas', +'BR-03' => 'Brazil: Amapa', +'BR-04' => 'Brazil: Amazonas', +'BR-05' => 'Brazil: Bahia', +'BR-06' => 'Brazil: Ceara', +'BR-07' => 'Brazil: Distrito Federal', +'BR-08' => 'Brazil: Espirito Santo', +'BR-29' => 'Brazil: Goias', +'BR-13' => 'Brazil: Maranhao', +'BR-11' => 'Brazil: Mato Grosso do Sul', +'BR-14' => 'Brazil: Mato Grosso', +'BR-15' => 'Brazil: Minas Gerais', +'BR-16' => 'Brazil: Para', +'BR-17' => 'Brazil: Paraiba', +'BR-18' => 'Brazil: Parana', +'BR-30' => 'Brazil: Pernambuco', +'BR-20' => 'Brazil: Piaui', +'BR-21' => 'Brazil: Rio de Janeiro', +'BR-22' => 'Brazil: Rio Grande do Norte', +'BR-23' => 'Brazil: Rio Grande do Sul', +'BR-24' => 'Brazil: Rondonia', +'BR-25' => 'Brazil: Roraima', +'BR-26' => 'Brazil: Santa Catarina', +'BR-27' => 'Brazil: Sao Paulo', +'BR-28' => 'Brazil: Sergipe', +'BR-31' => 'Brazil: Tocantins', + +'--BN' => '','-BN' => 'Brunei Darussalam', +'BN-07' => 'Brunei Darussalam: Alibori', +'BN-08' => 'Brunei Darussalam: Belait', +'BN-09' => 'Brunei Darussalam: Brunei and Muara', +'BN-11' => 'Brunei Darussalam: Collines', +'BN-13' => 'Brunei Darussalam: Donga', +'BN-12' => 'Brunei Darussalam: Kouffo', +'BN-14' => 'Brunei Darussalam: Littoral', +'BN-16' => 'Brunei Darussalam: Oueme', +'BN-17' => 'Brunei Darussalam: Plateau', +'BN-10' => 'Brunei Darussalam: Temburong', +'BN-15' => 'Brunei Darussalam: Tutong', +'BN-18' => 'Brunei Darussalam: Zou', + +'--BG' => '','-BG' => 'Bulgaria', +'BG-38' => 'Bulgaria: Blagoevgrad', +'BG-39' => 'Bulgaria: Burgas', +'BG-40' => 'Bulgaria: Dobrich', +'BG-41' => 'Bulgaria: Gabrovo', +'BG-42' => 'Bulgaria: Grad Sofiya', +'BG-43' => 'Bulgaria: Khaskovo', +'BG-44' => 'Bulgaria: Kurdzhali', +'BG-45' => 'Bulgaria: Kyustendil', +'BG-46' => 'Bulgaria: Lovech', +'BG-33' => 'Bulgaria: Mikhaylovgrad', +'BG-47' => 'Bulgaria: Montana', +'BG-48' => 'Bulgaria: Pazardzhik', +'BG-49' => 'Bulgaria: Pernik', +'BG-50' => 'Bulgaria: Pleven', +'BG-51' => 'Bulgaria: Plovdiv', +'BG-52' => 'Bulgaria: Razgrad', +'BG-53' => 'Bulgaria: Ruse', +'BG-54' => 'Bulgaria: Shumen', +'BG-55' => 'Bulgaria: Silistra', +'BG-56' => 'Bulgaria: Sliven', +'BG-57' => 'Bulgaria: Smolyan', +'BG-58' => 'Bulgaria: Sofiya', +'BG-59' => 'Bulgaria: Stara Zagora', +'BG-60' => 'Bulgaria: Turgovishte', +'BG-61' => 'Bulgaria: Varna', +'BG-62' => 'Bulgaria: Veliko Turnovo', +'BG-63' => 'Bulgaria: Vidin', +'BG-64' => 'Bulgaria: Vratsa', +'BG-65' => 'Bulgaria: Yambol', + +'--BF' => '','-BF' => 'Burkina Faso', +'BF-45' => 'Burkina Faso: Bale', +'BF-15' => 'Burkina Faso: Bam', +'BF-46' => 'Burkina Faso: Banwa', +'BF-47' => 'Burkina Faso: Bazega', +'BF-48' => 'Burkina Faso: Bougouriba', +'BF-49' => 'Burkina Faso: Boulgou', +'BF-19' => 'Burkina Faso: Boulkiemde', +'BF-20' => 'Burkina Faso: Ganzourgou', +'BF-21' => 'Burkina Faso: Gnagna', +'BF-50' => 'Burkina Faso: Gourma', +'BF-51' => 'Burkina Faso: Houet', +'BF-52' => 'Burkina Faso: Ioba', +'BF-53' => 'Burkina Faso: Kadiogo', +'BF-54' => 'Burkina Faso: Kenedougou', +'BF-55' => 'Burkina Faso: Komoe', +'BF-56' => 'Burkina Faso: Komondjari', +'BF-57' => 'Burkina Faso: Kompienga', +'BF-58' => 'Burkina Faso: Kossi', +'BF-59' => 'Burkina Faso: Koulpelogo', +'BF-28' => 'Burkina Faso: Kouritenga', +'BF-60' => 'Burkina Faso: Kourweogo', +'BF-61' => 'Burkina Faso: Leraba', +'BF-62' => 'Burkina Faso: Loroum', +'BF-63' => 'Burkina Faso: Mouhoun', +'BF-64' => 'Burkina Faso: Namentenga', +'BF-65' => 'Burkina Faso: Naouri', +'BF-66' => 'Burkina Faso: Nayala', +'BF-67' => 'Burkina Faso: Noumbiel', +'BF-68' => 'Burkina Faso: Oubritenga', +'BF-33' => 'Burkina Faso: Oudalan', +'BF-34' => 'Burkina Faso: Passore', +'BF-69' => 'Burkina Faso: Poni', +'BF-36' => 'Burkina Faso: Sanguie', +'BF-70' => 'Burkina Faso: Sanmatenga', +'BF-71' => 'Burkina Faso: Seno', +'BF-72' => 'Burkina Faso: Sissili', +'BF-40' => 'Burkina Faso: Soum', +'BF-73' => 'Burkina Faso: Sourou', +'BF-42' => 'Burkina Faso: Tapoa', +'BF-74' => 'Burkina Faso: Tuy', +'BF-75' => 'Burkina Faso: Yagha', +'BF-76' => 'Burkina Faso: Yatenga', +'BF-77' => 'Burkina Faso: Ziro', +'BF-78' => 'Burkina Faso: Zondoma', +'BF-44' => 'Burkina Faso: Zoundweogo', + +'--BI' => '','-BI' => 'Burundi', +'BI-09' => 'Burundi: Bubanza', +'BI-02' => 'Burundi: Bujumbura', +'BI-10' => 'Burundi: Bururi', +'BI-11' => 'Burundi: Cankuzo', +'BI-12' => 'Burundi: Cibitoke', +'BI-13' => 'Burundi: Gitega', +'BI-14' => 'Burundi: Karuzi', +'BI-15' => 'Burundi: Kayanza', +'BI-16' => 'Burundi: Kirundo', +'BI-17' => 'Burundi: Makamba', +'BI-22' => 'Burundi: Muramvya', +'BI-18' => 'Burundi: Muyinga', +'BI-23' => 'Burundi: Mwaro', +'BI-19' => 'Burundi: Ngozi', +'BI-20' => 'Burundi: Rutana', +'BI-21' => 'Burundi: Ruyigi', + +'--KH' => '','-KH' => 'Cambodia', +'KH-29' => 'Cambodia: Batdambang', +'KH-02' => 'Cambodia: Kampong Cham', +'KH-03' => 'Cambodia: Kampong Chhnang', +'KH-04' => 'Cambodia: Kampong Spoe', +'KH-05' => 'Cambodia: Kampong Thum', +'KH-06' => 'Cambodia: Kampot', +'KH-07' => 'Cambodia: Kandal', +'KH-08' => 'Cambodia: Kaoh Kong', +'KH-09' => 'Cambodia: Kracheh', +'KH-10' => 'Cambodia: Mondol Kiri', +'KH-30' => 'Cambodia: Pailin', +'KH-11' => 'Cambodia: Phnum Penh', +'KH-12' => 'Cambodia: Pouthisat', +'KH-13' => 'Cambodia: Preah Vihear', +'KH-14' => 'Cambodia: Prey Veng', +'KH-15' => 'Cambodia: Rotanokiri', +'KH-16' => 'Cambodia: Siemreab-Otdar Meanchey', +'KH-17' => 'Cambodia: Stoeng Treng', +'KH-18' => 'Cambodia: Svay Rieng', +'KH-19' => 'Cambodia: Takev', + +'--CM' => '','-CM' => 'Cameroon', +'CM-10' => 'Cameroon: Adamaoua', +'CM-11' => 'Cameroon: Centre', +'CM-04' => 'Cameroon: Est', +'CM-12' => 'Cameroon: Extreme-Nord', +'CM-05' => 'Cameroon: Littoral', +'CM-13' => 'Cameroon: Nord', +'CM-07' => 'Cameroon: Nord-Ouest', +'CM-08' => 'Cameroon: Ouest', +'CM-14' => 'Cameroon: Sud', +'CM-09' => 'Cameroon: Sud-Ouest', + +'--CA' => '','-CA' => 'Canada', +'CA-AB' => 'Canada: Alberta', +'CA-BC' => 'Canada: British Columbia', +'CA-MB' => 'Canada: Manitoba', +'CA-NB' => 'Canada: New Brunswick', +'CA-NL' => 'Canada: Newfoundland', +'CA-NT' => 'Canada: Northwest Territories', +'CA-NS' => 'Canada: Nova Scotia', +'CA-NU' => 'Canada: Nunavut', +'CA-ON' => 'Canada: Ontario', +'CA-PE' => 'Canada: Prince Edward Island', +'CA-QC' => 'Canada: Quebec', +'CA-SK' => 'Canada: Saskatchewan', +'CA-YT' => 'Canada: Yukon Territory', + +'--CV' => '','-CV' => 'Cape Verde', +'CV-01' => 'Cape Verde: Boa Vista', +'CV-02' => 'Cape Verde: Brava', +'CV-04' => 'Cape Verde: Maio', +'CV-13' => 'Cape Verde: Mosteiros', +'CV-05' => 'Cape Verde: Paul', +'CV-14' => 'Cape Verde: Praia', +'CV-07' => 'Cape Verde: Ribeira Grande', +'CV-08' => 'Cape Verde: Sal', +'CV-15' => 'Cape Verde: Santa Catarina', +'CV-16' => 'Cape Verde: Santa Cruz', +'CV-17' => 'Cape Verde: Sao Domingos', +'CV-18' => 'Cape Verde: Sao Filipe', +'CV-19' => 'Cape Verde: Sao Miguel', +'CV-10' => 'Cape Verde: Sao Nicolau', +'CV-11' => 'Cape Verde: Sao Vicente', +'CV-20' => 'Cape Verde: Tarrafal', + +'--KY' => '','-KY' => 'Cayman Islands', +'KY-01' => 'Cayman Islands: Creek', +'KY-02' => 'Cayman Islands: Eastern', +'KY-03' => 'Cayman Islands: Midland', +'KY-04' => 'Cayman Islands: South Town', +'KY-05' => 'Cayman Islands: Spot Bay', +'KY-06' => 'Cayman Islands: Stake Bay', +'KY-07' => 'Cayman Islands: West End', +'KY-08' => 'Cayman Islands: Western', + +'--CF' => '','-CF' => 'Central African Republic', +'CF-01' => 'Central African Republic: Bamingui-Bangoran', +'CF-18' => 'Central African Republic: Bangui', +'CF-02' => 'Central African Republic: Basse-Kotto', +'CF-03' => 'Central African Republic: Haute-Kotto', +'CF-05' => 'Central African Republic: Haut-Mbomou', +'CF-06' => 'Central African Republic: Kemo', +'CF-07' => 'Central African Republic: Lobaye', +'CF-04' => 'Central African Republic: Mambere-Kadei', +'CF-08' => 'Central African Republic: Mbomou', +'CF-15' => 'Central African Republic: Nana-Grebizi', +'CF-09' => 'Central African Republic: Nana-Mambere', +'CF-17' => 'Central African Republic: Ombella-Mpoko', +'CF-11' => 'Central African Republic: Ouaka', +'CF-12' => 'Central African Republic: Ouham', +'CF-13' => 'Central African Republic: Ouham-Pende', +'CF-16' => 'Central African Republic: Sangha-Mbaere', +'CF-14' => 'Central African Republic: Vakaga', + +'--TD' => '','-TD' => 'Chad', +'TD-01' => 'Chad: Batha', +'TD-02' => 'Chad: Biltine', +'TD-03' => 'Chad: Borkou-Ennedi-Tibesti', +'TD-04' => 'Chad: Chari-Baguirmi', +'TD-05' => 'Chad: Guera', +'TD-06' => 'Chad: Kanem', +'TD-07' => 'Chad: Lac', +'TD-08' => 'Chad: Logone Occidental', +'TD-09' => 'Chad: Logone Oriental', +'TD-10' => 'Chad: Mayo-Kebbi', +'TD-11' => 'Chad: Moyen-Chari', +'TD-12' => 'Chad: Ouaddai', +'TD-13' => 'Chad: Salamat', +'TD-14' => 'Chad: Tandjile', + +'--CL' => '','-CL' => 'Chile', +'CL-02' => 'Chile: Aisen del General Carlos Ibanez del Campo', +'CL-03' => 'Chile: Antofagasta', +'CL-04' => 'Chile: Araucania', +'CL-05' => 'Chile: Atacama', +'CL-06' => 'Chile: Bio-Bio', +'CL-07' => 'Chile: Coquimbo', +'CL-08' => 'Chile: Libertador General Bernardo O\'Higgins', +'CL-09' => 'Chile: Los Lagos', +'CL-10' => 'Chile: Magallanes y de la Antartica Chilena', +'CL-11' => 'Chile: Maule', +'CL-12' => 'Chile: Region Metropolitana', +'CL-13' => 'Chile: Tarapaca', +'CL-01' => 'Chile: Valparaiso', + +'--CN' => '','-CN' => 'China', +'CN-01' => 'China: Anhui', +'CN-22' => 'China: Beijing', +'CN-33' => 'China: Chongqing', +'CN-07' => 'China: Fujian', +'CN-15' => 'China: Gansu', +'CN-30' => 'China: Guangdong', +'CN-16' => 'China: Guangxi', +'CN-18' => 'China: Guizhou', +'CN-31' => 'China: Hainan', +'CN-10' => 'China: Hebei', +'CN-08' => 'China: Heilongjiang', +'CN-09' => 'China: Henan', +'CN-12' => 'China: Hubei', +'CN-11' => 'China: Hunan', +'CN-04' => 'China: Jiangsu', +'CN-03' => 'China: Jiangxi', +'CN-05' => 'China: Jilin', +'CN-19' => 'China: Liaoning', +'CN-20' => 'China: Nei Mongol', +'CN-21' => 'China: Ningxia', +'CN-06' => 'China: Qinghai', +'CN-26' => 'China: Shaanxi', +'CN-25' => 'China: Shandong', +'CN-23' => 'China: Shanghai', +'CN-24' => 'China: Shanxi', +'CN-32' => 'China: Sichuan', +'CN-28' => 'China: Tianjin', +'CN-13' => 'China: Xinjiang', +'CN-14' => 'China: Xizang', +'CN-29' => 'China: Yunnan', +'CN-02' => 'China: Zhejiang', + +'--CO' => '','-CO' => 'Colombia', +'CO-01' => 'Colombia: Amazonas', +'CO-02' => 'Colombia: Antioquia', +'CO-03' => 'Colombia: Arauca', +'CO-04' => 'Colombia: Atlantico', +'CO-35' => 'Colombia: Bolivar', +'CO-36' => 'Colombia: Boyaca', +'CO-37' => 'Colombia: Caldas', +'CO-08' => 'Colombia: Caqueta', +'CO-32' => 'Colombia: Casanare', +'CO-09' => 'Colombia: Cauca', +'CO-10' => 'Colombia: Cesar', +'CO-11' => 'Colombia: Choco', +'CO-12' => 'Colombia: Cordoba', +'CO-33' => 'Colombia: Cundinamarca', +'CO-34' => 'Colombia: Distrito Especial', +'CO-15' => 'Colombia: Guainia', +'CO-14' => 'Colombia: Guaviare', +'CO-16' => 'Colombia: Huila', +'CO-17' => 'Colombia: La Guajira', +'CO-38' => 'Colombia: Magdalena', +'CO-19' => 'Colombia: Meta', +'CO-20' => 'Colombia: Narino', +'CO-21' => 'Colombia: Norte de Santander', +'CO-22' => 'Colombia: Putumayo', +'CO-23' => 'Colombia: Quindio', +'CO-24' => 'Colombia: Risaralda', +'CO-25' => 'Colombia: San Andres y Providencia', +'CO-26' => 'Colombia: Santander', +'CO-27' => 'Colombia: Sucre', +'CO-28' => 'Colombia: Tolima', +'CO-29' => 'Colombia: Valle del Cauca', +'CO-30' => 'Colombia: Vaupes', +'CO-31' => 'Colombia: Vichada', + +'--KM' => '','-KM' => 'Comoros', +'KM-01' => 'Comoros: Anjouan', +'KM-02' => 'Comoros: Grande Comore', +'KM-03' => 'Comoros: Moheli', + +'--CD' => '','-CD' => 'Congo', +'CD-01' => 'Congo: Bandundu', +'CD-08' => 'Congo: Bas-Congo', + +'--CG' => '','-CG' => 'Congo', +'CG-01' => 'Congo: Bouenza', +'CG-12' => 'Congo: Brazzamark', +'CG-03' => 'Congo: Cuvette', + +'--CD' => '','-CD' => 'Congo', +'CD-02' => 'Congo: Equateur', +'CD-03' => 'Congo: Kasai-Occidental', +'CD-04' => 'Congo: Kasai-Oriental', +'CD-05' => 'Congo: Katanga', +'CD-06' => 'Congo: Kinshasa', +'CD-07' => 'Congo: Kivu', + +'--CG' => '','-CG' => 'Congo', +'CG-04' => 'Congo: Kouilou', +'CG-05' => 'Congo: Lekoumou', +'CG-06' => 'Congo: Likouala', + +'--CD' => '','-CD' => 'Congo', +'CD-10' => 'Congo: Maniema', + +'--CG' => '','-CG' => 'Congo', +'CG-07' => 'Congo: Niari', + +'--CD' => '','-CD' => 'Congo', +'CD-11' => 'Congo: Nord-Kivu', +'CD-09' => 'Congo: Orientale', + +'--CG' => '','-CG' => 'Congo', +'CG-08' => 'Congo: Plateaux', +'CG-11' => 'Congo: Pool', +'CG-10' => 'Congo: Sangha', + +'--CD' => '','-CD' => 'Congo', +'CD-12' => 'Congo: Sud-Kivu', + +'--CR' => '','-CR' => 'Costa Rica', +'CR-01' => 'Costa Rica: Alajuela', +'CR-02' => 'Costa Rica: Cartago', +'CR-03' => 'Costa Rica: Guanacaste', +'CR-04' => 'Costa Rica: Heredia', +'CR-06' => 'Costa Rica: Limon', +'CR-07' => 'Costa Rica: Puntarenas', +'CR-08' => 'Costa Rica: San Jose', + +'--CI' => '','-CI' => 'Cote D'Ivoire', +'CI-01' => 'Cote D\'Ivoire: Abengourou', +'CI-61' => 'Cote D\'Ivoire: Abidjan', +'CI-62' => 'Cote D\'Ivoire: Aboisso', +'CI-63' => 'Cote D\'Ivoire: Adiake', +'CI-05' => 'Cote D\'Ivoire: Adzope', +'CI-06' => 'Cote D\'Ivoire: Agbomark', +'CI-64' => 'Cote D\'Ivoire: Alepe', +'CI-36' => 'Cote D\'Ivoire: Bangolo', +'CI-37' => 'Cote D\'Ivoire: Beoumi', +'CI-07' => 'Cote D\'Ivoire: Biankouma', +'CI-65' => 'Cote D\'Ivoire: Bocanda', +'CI-38' => 'Cote D\'Ivoire: Bondoukou', +'CI-27' => 'Cote D\'Ivoire: Bongouanou', +'CI-39' => 'Cote D\'Ivoire: Bouafle', +'CI-40' => 'Cote D\'Ivoire: Bouake', +'CI-11' => 'Cote D\'Ivoire: Bouna', +'CI-12' => 'Cote D\'Ivoire: Boundiali', +'CI-03' => 'Cote D\'Ivoire: Dabakala', +'CI-66' => 'Cote D\'Ivoire: Dabou', +'CI-41' => 'Cote D\'Ivoire: Daloa', +'CI-14' => 'Cote D\'Ivoire: Danane', +'CI-42' => 'Cote D\'Ivoire: Daoukro', +'CI-67' => 'Cote D\'Ivoire: Dimbokro', +'CI-16' => 'Cote D\'Ivoire: Divo', +'CI-44' => 'Cote D\'Ivoire: Duekoue', +'CI-17' => 'Cote D\'Ivoire: Ferkessedougou', +'CI-18' => 'Cote D\'Ivoire: Gagnoa', +'CI-68' => 'Cote D\'Ivoire: Grand-Bassam', +'CI-45' => 'Cote D\'Ivoire: Grand-Lahou', +'CI-69' => 'Cote D\'Ivoire: Guiglo', +'CI-28' => 'Cote D\'Ivoire: Issia', +'CI-70' => 'Cote D\'Ivoire: Jacquemark', +'CI-20' => 'Cote D\'Ivoire: Katiola', +'CI-21' => 'Cote D\'Ivoire: Korhogo', +'CI-29' => 'Cote D\'Ivoire: Lakota', +'CI-47' => 'Cote D\'Ivoire: Man', +'CI-30' => 'Cote D\'Ivoire: Mankono', +'CI-48' => 'Cote D\'Ivoire: Mbahiakro', +'CI-23' => 'Cote D\'Ivoire: Odienne', +'CI-31' => 'Cote D\'Ivoire: Oume', +'CI-49' => 'Cote D\'Ivoire: Sakassou', +'CI-50' => 'Cote D\'Ivoire: San Pedro', +'CI-51' => 'Cote D\'Ivoire: Sassandra', +'CI-25' => 'Cote D\'Ivoire: Seguela', +'CI-52' => 'Cote D\'Ivoire: Sinfra', +'CI-32' => 'Cote D\'Ivoire: Soubre', +'CI-53' => 'Cote D\'Ivoire: Tabou', +'CI-54' => 'Cote D\'Ivoire: Tanda', +'CI-55' => 'Cote D\'Ivoire: Tiassale', +'CI-71' => 'Cote D\'Ivoire: Tiebissou', +'CI-33' => 'Cote D\'Ivoire: Tingrela', +'CI-26' => 'Cote D\'Ivoire: Touba', +'CI-72' => 'Cote D\'Ivoire: Toulepleu', +'CI-56' => 'Cote D\'Ivoire: Toumodi', +'CI-57' => 'Cote D\'Ivoire: Vavoua', +'CI-73' => 'Cote D\'Ivoire: Yamoussoukro', +'CI-34' => 'Cote D\'Ivoire: Zuenoula', + +'--HR' => '','-HR' => 'Croatia', +'HR-01' => 'Croatia: Bjelovarsko-Bilogorska', +'HR-02' => 'Croatia: Brodsko-Posavska', +'HR-03' => 'Croatia: Dubrovacko-Neretvanska', +'HR-21' => 'Croatia: Grad Zagreb', +'HR-04' => 'Croatia: Istarska', +'HR-05' => 'Croatia: Karlovacka', +'HR-06' => 'Croatia: Koprivnicko-Krizevacka', +'HR-07' => 'Croatia: Krapinsko-Zagorska', +'HR-08' => 'Croatia: Licko-Senjska', +'HR-09' => 'Croatia: Medimurska', +'HR-10' => 'Croatia: Osjecko-Baranjska', +'HR-11' => 'Croatia: Pozesko-Slavonska', +'HR-12' => 'Croatia: Primorsko-Goranska', +'HR-13' => 'Croatia: Sibensko-Kninska', +'HR-14' => 'Croatia: Sisacko-Moslavacka', +'HR-15' => 'Croatia: Splitsko-Dalmatinska', +'HR-16' => 'Croatia: Varazdinska', +'HR-17' => 'Croatia: Viroviticko-Podravska', +'HR-18' => 'Croatia: Vukovarsko-Srijemska', +'HR-19' => 'Croatia: Zadarska', +'HR-20' => 'Croatia: Zagrebacka', + +'--CU' => '','-CU' => 'Cuba', +'CU-05' => 'Cuba: Camaguey', +'CU-07' => 'Cuba: Ciego de Avila', +'CU-08' => 'Cuba: Cienfuegos', +'CU-02' => 'Cuba: Ciudad de la Habana', +'CU-09' => 'Cuba: Granma', +'CU-10' => 'Cuba: Guantanamo', +'CU-12' => 'Cuba: Holguin', +'CU-04' => 'Cuba: Isla de la Juventud', +'CU-11' => 'Cuba: La Habana', +'CU-13' => 'Cuba: Las Tunas', +'CU-03' => 'Cuba: Matanzas', +'CU-01' => 'Cuba: Pinar del Rio', +'CU-14' => 'Cuba: Sancti Spiritus', +'CU-15' => 'Cuba: Santiago de Cuba', +'CU-16' => 'Cuba: Villa Clara', + +'--CY' => '','-CY' => 'Cyprus', +'CY-01' => 'Cyprus: Famagusta', +'CY-02' => 'Cyprus: Kyrenia', +'CY-03' => 'Cyprus: Larnaca', +'CY-05' => 'Cyprus: Limassol', +'CY-04' => 'Cyprus: Nicosia', +'CY-06' => 'Cyprus: Paphos', + +'--CZ' => '','-CZ' => 'Czech Republic', +'CZ-03' => 'Czech Republic: Blansko', +'CZ-04' => 'Czech Republic: Breclav', +'CZ-52' => 'Czech Republic: Hlavni Mesto Praha', +'CZ-20' => 'Czech Republic: Hradec Kralove', +'CZ-21' => 'Czech Republic: Jablonec nad Nisou', +'CZ-23' => 'Czech Republic: Jiein', +'CZ-24' => 'Czech Republic: Jihlava', +'CZ-79' => 'Czech Republic: Jihocesky Kraj', +'CZ-78' => 'Czech Republic: Jihomoravsky Kraj', +'CZ-81' => 'Czech Republic: Karlovarsky Kraj', +'CZ-30' => 'Czech Republic: Kolin', +'CZ-82' => 'Czech Republic: Kralovehradecky Kraj', +'CZ-33' => 'Czech Republic: Liberec', +'CZ-83' => 'Czech Republic: Liberecky Kraj', +'CZ-36' => 'Czech Republic: Melnik', +'CZ-37' => 'Czech Republic: Mlada Boleslav', +'CZ-85' => 'Czech Republic: Moravskoslezsky Kraj', +'CZ-39' => 'Czech Republic: Nachod', +'CZ-41' => 'Czech Republic: Nymburk', +'CZ-84' => 'Czech Republic: Olomoucky Kraj', +'CZ-45' => 'Czech Republic: Pardubice', +'CZ-86' => 'Czech Republic: Pardubicky Kraj', +'CZ-87' => 'Czech Republic: Plzensky Kraj', +'CZ-61' => 'Czech Republic: Semily', +'CZ-88' => 'Czech Republic: Stredocesky Kraj', +'CZ-70' => 'Czech Republic: Trutnov', +'CZ-89' => 'Czech Republic: Ustecky Kraj', +'CZ-80' => 'Czech Republic: Vysocina', +'CZ-90' => 'Czech Republic: Zlinsky Kraj', + +'--DK' => '','-DK' => 'Denmark', +'DK-01' => 'Denmark: Arhus', +'DK-02' => 'Denmark: Bornholm', +'DK-03' => 'Denmark: Frederiksborg', +'DK-04' => 'Denmark: Fyn', +'DK-05' => 'Denmark: Kobenhavn', +'DK-07' => 'Denmark: Nordjylland', +'DK-08' => 'Denmark: Ribe', +'DK-09' => 'Denmark: Ringkobing', +'DK-10' => 'Denmark: Roskilde', +'DK-11' => 'Denmark: Sonderjylland', +'DK-06' => 'Denmark: Staden Kobenhavn', +'DK-12' => 'Denmark: Storstrom', +'DK-13' => 'Denmark: Vejle', +'DK-14' => 'Denmark: Vestsjalland', +'DK-15' => 'Denmark: Viborg', + +'--DJ' => '','-DJ' => 'Djibouti', +'DJ-02' => 'Djibouti: Dikhil', +'DJ-03' => 'Djibouti: Djibouti', +'DJ-04' => 'Djibouti: Obock', +'DJ-05' => 'Djibouti: Tadjoura', + +'--DM' => '','-DM' => 'Dominica', +'DM-02' => 'Dominica: Saint Andrew', +'DM-03' => 'Dominica: Saint David', +'DM-04' => 'Dominica: Saint George', +'DM-05' => 'Dominica: Saint John', +'DM-06' => 'Dominica: Saint Joseph', +'DM-07' => 'Dominica: Saint Luke', +'DM-08' => 'Dominica: Saint Mark', +'DM-09' => 'Dominica: Saint Patrick', +'DM-10' => 'Dominica: Saint Paul', +'DM-11' => 'Dominica: Saint Peter', + +'--DO' => '','-DO' => 'Dominican Republic', +'DO-01' => 'Dominican Republic: Azua', +'DO-02' => 'Dominican Republic: Baoruco', +'DO-03' => 'Dominican Republic: Barahona', +'DO-04' => 'Dominican Republic: Dajabon', +'DO-05' => 'Dominican Republic: Distrito Nacional', +'DO-06' => 'Dominican Republic: Duarte', +'DO-28' => 'Dominican Republic: El Seibo', +'DO-11' => 'Dominican Republic: Elias Pina', +'DO-08' => 'Dominican Republic: Espaillat', +'DO-29' => 'Dominican Republic: Hato Mayor', +'DO-09' => 'Dominican Republic: Independencia', +'DO-10' => 'Dominican Republic: La Altagracia', +'DO-12' => 'Dominican Republic: La Romana', +'DO-30' => 'Dominican Republic: La Vega', +'DO-14' => 'Dominican Republic: Maria Trinidad Sanchez', +'DO-31' => 'Dominican Republic: Monsenor Nouel', +'DO-15' => 'Dominican Republic: Monte Cristi', +'DO-32' => 'Dominican Republic: Monte Plata', +'DO-16' => 'Dominican Republic: Pedernales', +'DO-17' => 'Dominican Republic: Peravia', +'DO-18' => 'Dominican Republic: Puerto Plata', +'DO-19' => 'Dominican Republic: Salcedo', +'DO-20' => 'Dominican Republic: Samana', +'DO-33' => 'Dominican Republic: San Cristobal', +'DO-23' => 'Dominican Republic: San Juan', +'DO-24' => 'Dominican Republic: San Pedro De Macoris', +'DO-21' => 'Dominican Republic: Sanchez Ramirez', +'DO-26' => 'Dominican Republic: Santiago Rodriguez', +'DO-25' => 'Dominican Republic: Santiago', +'DO-27' => 'Dominican Republic: Valverde', + +'--EC' => '','-EC' => 'Ecuador', +'EC-02' => 'Ecuador: Azuay', +'EC-03' => 'Ecuador: Bolivar', +'EC-04' => 'Ecuador: Canar', +'EC-05' => 'Ecuador: Carchi', +'EC-06' => 'Ecuador: Chimborazo', +'EC-07' => 'Ecuador: Cotopaxi', +'EC-08' => 'Ecuador: El Oro', +'EC-09' => 'Ecuador: Esmeraldas', +'EC-01' => 'Ecuador: Galapagos', +'EC-10' => 'Ecuador: Guayas', +'EC-11' => 'Ecuador: Imbabura', +'EC-12' => 'Ecuador: Loja', +'EC-13' => 'Ecuador: Los Rios', +'EC-14' => 'Ecuador: Manabi', +'EC-15' => 'Ecuador: Morona-Santiago', +'EC-23' => 'Ecuador: Napo', +'EC-24' => 'Ecuador: Orellana', +'EC-17' => 'Ecuador: Pastaza', +'EC-18' => 'Ecuador: Pichincha', +'EC-22' => 'Ecuador: Sucumbios', +'EC-19' => 'Ecuador: Tungurahua', +'EC-20' => 'Ecuador: Zamora-Chinchipe', + +'--EG' => '','-EG' => 'Egypt', +'EG-01' => 'Egypt: Ad Daqahliyah', +'EG-02' => 'Egypt: Al Bahr al Ahmar', +'EG-03' => 'Egypt: Al Buhayrah', +'EG-04' => 'Egypt: Al Fayyum', +'EG-05' => 'Egypt: Al Gharbiyah', +'EG-06' => 'Egypt: Al Iskandariyah', +'EG-07' => 'Egypt: Al Isma\'iliyah', +'EG-08' => 'Egypt: Al Jizah', +'EG-09' => 'Egypt: Al Minufiyah', +'EG-10' => 'Egypt: Al Minya', +'EG-11' => 'Egypt: Al Qahirah', +'EG-12' => 'Egypt: Al Qalyubiyah', +'EG-13' => 'Egypt: Al Wadi al Jadid', +'EG-15' => 'Egypt: As Suways', +'EG-14' => 'Egypt: Ash Sharqiyah', +'EG-16' => 'Egypt: Aswan', +'EG-17' => 'Egypt: Asyut', +'EG-18' => 'Egypt: Bani Suwayf', +'EG-19' => 'Egypt: Bur Sa\'id', +'EG-20' => 'Egypt: Dumyat', +'EG-26' => 'Egypt: Janub Sina\'', +'EG-21' => 'Egypt: Kafr ash Shaykh', +'EG-22' => 'Egypt: Matruh', +'EG-23' => 'Egypt: Qina', +'EG-27' => 'Egypt: Shamal Sina\'', +'EG-24' => 'Egypt: Suhaj', + +'--SV' => '','-SV' => 'El Salvador', +'SV-01' => 'El Salvador: Ahuachapan', +'SV-02' => 'El Salvador: Cabanas', +'SV-03' => 'El Salvador: Chalatenango', +'SV-04' => 'El Salvador: Cuscatlan', +'SV-05' => 'El Salvador: La Libertad', +'SV-06' => 'El Salvador: La Paz', +'SV-07' => 'El Salvador: La Union', +'SV-08' => 'El Salvador: Morazan', +'SV-09' => 'El Salvador: San Miguel', +'SV-10' => 'El Salvador: San Salvador', +'SV-12' => 'El Salvador: San Vicente', +'SV-11' => 'El Salvador: Santa Ana', +'SV-13' => 'El Salvador: Sonsonate', +'SV-14' => 'El Salvador: Usulutan', + +'--GQ' => '','-GQ' => 'Equatorial Guinea', +'GQ-03' => 'Equatorial Guinea: Annobon', +'GQ-04' => 'Equatorial Guinea: Bioko Norte', +'GQ-05' => 'Equatorial Guinea: Bioko Sur', +'GQ-06' => 'Equatorial Guinea: Centro Sur', +'GQ-07' => 'Equatorial Guinea: Kie-Ntem', +'GQ-08' => 'Equatorial Guinea: Litoral', +'GQ-09' => 'Equatorial Guinea: Wele-Nzas', + +'--EE' => '','-EE' => 'Estonia', +'EE-01' => 'Estonia: Harjumaa', +'EE-02' => 'Estonia: Hiiumaa', +'EE-03' => 'Estonia: Ida-Virumaa', +'EE-04' => 'Estonia: Jarvamaa', +'EE-05' => 'Estonia: Jogevamaa', +'EE-06' => 'Estonia: Kohtla-Jarve', +'EE-07' => 'Estonia: Laanemaa', +'EE-08' => 'Estonia: Laane-Virumaa', +'EE-09' => 'Estonia: Narva', +'EE-10' => 'Estonia: Parnu', +'EE-11' => 'Estonia: Parnumaa', +'EE-12' => 'Estonia: Polvamaa', +'EE-13' => 'Estonia: Raplamaa', +'EE-14' => 'Estonia: Saaremaa', +'EE-15' => 'Estonia: Sillamae', +'EE-16' => 'Estonia: Tallinn', +'EE-17' => 'Estonia: Tartu', +'EE-18' => 'Estonia: Tartumaa', +'EE-19' => 'Estonia: Valgamaa', +'EE-20' => 'Estonia: Viljandimaa', +'EE-21' => 'Estonia: Vorumaa', + +'--ET' => '','-ET' => 'Ethiopia', +'ET-10' => 'Ethiopia: Addis Abeba', +'ET-44' => 'Ethiopia: Adis Abeba', +'ET-14' => 'Ethiopia: Afar', +'ET-45' => 'Ethiopia: Afar', +'ET-46' => 'Ethiopia: Amara', +'ET-02' => 'Ethiopia: Amhara', +'ET-13' => 'Ethiopia: Benishangul', +'ET-47' => 'Ethiopia: Binshangul Gumuz', +'ET-48' => 'Ethiopia: Dire Dawa', +'ET-49' => 'Ethiopia: Gambela Hizboch', +'ET-08' => 'Ethiopia: Gambella', +'ET-50' => 'Ethiopia: Hareri Hizb', +'ET-51' => 'Ethiopia: Oromiya', +'ET-07' => 'Ethiopia: Somali', +'ET-11' => 'Ethiopia: Southern', +'ET-52' => 'Ethiopia: Sumale', +'ET-12' => 'Ethiopia: Tigray', +'ET-53' => 'Ethiopia: Tigray', +'ET-54' => 'Ethiopia: YeDebub Biheroch Bihereseboch na Hizboch', + +'--FJ' => '','-FJ' => 'Fiji', +'FJ-01' => 'Fiji: Central', +'FJ-02' => 'Fiji: Eastern', +'FJ-03' => 'Fiji: Northern', +'FJ-04' => 'Fiji: Rotuma', +'FJ-05' => 'Fiji: Western', + +'--FI' => '','-FI' => 'Finland', +'FI-01' => 'Finland: Åland', +'FI-14' => 'Finland: Eastern Finland', +'FI-06' => 'Finland: Lapland', +'FI-08' => 'Finland: Oulu', +'FI-13' => 'Finland: Southern Finland', +'FI-15' => 'Finland: Western Finland', + +'--FR' => '','-FR' => 'France', +'FR-C1' => 'France: Alsace', +'FR-97' => 'France: Aquitaine', +'FR-98' => 'France: Auvergne', +'FR-99' => 'France: Basse-Normandie', +'FR-A1' => 'France: Bourgogne', +'FR-A2' => 'France: Bretagne', +'FR-A3' => 'France: Centre', +'FR-A4' => 'France: Champagne-Ardenne', +'FR-A5' => 'France: Corse', +'FR-A6' => 'France: Franche-Comte', +'FR-A7' => 'France: Haute-Normandie', +'FR-A8' => 'France: Ile-de-France', +'FR-A9' => 'France: Languedoc-Roussillon', +'FR-B1' => 'France: Limousin', +'FR-B2' => 'France: Lorraine', +'FR-B3' => 'France: Midi-Pyrenees', +'FR-B4' => 'France: Nord-Pas-de-Calais', +'FR-B5' => 'France: Pays de la Loire', +'FR-B6' => 'France: Picardie', +'FR-B7' => 'France: Poitou-Charentes', +'FR-B8' => 'France: Provence-Alpes-Cote d\'Azur', +'FR-B9' => 'France: Rhone-Alpes', + +'--GA' => '','-GA' => 'Gabon', +'GA-01' => 'Gabon: Estuaire', +'GA-02' => 'Gabon: Haut-Ogooue', +'GA-03' => 'Gabon: Moyen-Ogooue', +'GA-04' => 'Gabon: Ngounie', +'GA-05' => 'Gabon: Nyanga', +'GA-06' => 'Gabon: Ogooue-Ivindo', +'GA-07' => 'Gabon: Ogooue-Lolo', +'GA-08' => 'Gabon: Ogooue-Maritime', +'GA-09' => 'Gabon: Woleu-Ntem', + +'--GM' => '','-GM' => 'Gambia', +'GM-01' => 'Gambia: Banjul', +'GM-02' => 'Gambia: Lower River', +'GM-03' => 'Gambia: MacCarthy Island', +'GM-07' => 'Gambia: North Bank', +'GM-04' => 'Gambia: Upper River', +'GM-05' => 'Gambia: Western', + +'--GE' => '','-GE' => 'Georgia', +'GE-01' => 'Georgia: Abashis Raioni', +'GE-02' => 'Georgia: Abkhazia', +'GE-03' => 'Georgia: Adigenis Raioni', +'GE-04' => 'Georgia: Ajaria', +'GE-05' => 'Georgia: Akhalgoris Raioni', +'GE-06' => 'Georgia: Akhalk\'alak\'is Raioni', +'GE-07' => 'Georgia: Akhalts\'ikhis Raioni', +'GE-08' => 'Georgia: Akhmetis Raioni', +'GE-09' => 'Georgia: Ambrolauris Raioni', +'GE-10' => 'Georgia: Aspindzis Raioni', +'GE-11' => 'Georgia: Baghdat\'is Raioni', +'GE-12' => 'Georgia: Bolnisis Raioni', +'GE-13' => 'Georgia: Borjomis Raioni', +'GE-14' => 'Georgia: Chiat\'ura', +'GE-15' => 'Georgia: Ch\'khorotsqus Raioni', +'GE-16' => 'Georgia: Ch\'okhatauris Raioni', +'GE-17' => 'Georgia: Dedop\'listsqaros Raioni', +'GE-18' => 'Georgia: Dmanisis Raioni', +'GE-19' => 'Georgia: Dushet\'is Raioni', +'GE-20' => 'Georgia: Gardabanis Raioni', +'GE-21' => 'Georgia: Gori', +'GE-22' => 'Georgia: Goris Raioni', +'GE-23' => 'Georgia: Gurjaanis Raioni', +'GE-24' => 'Georgia: Javis Raioni', +'GE-25' => 'Georgia: K\'arelis Raioni', +'GE-26' => 'Georgia: Kaspis Raioni', +'GE-27' => 'Georgia: Kharagaulis Raioni', +'GE-28' => 'Georgia: Khashuris Raioni', +'GE-29' => 'Georgia: Khobis Raioni', +'GE-30' => 'Georgia: Khonis Raioni', +'GE-31' => 'Georgia: K\'ut\'aisi', +'GE-32' => 'Georgia: Lagodekhis Raioni', +'GE-33' => 'Georgia: Lanch\'khut\'is Raioni', +'GE-34' => 'Georgia: Lentekhis Raioni', +'GE-35' => 'Georgia: Marneulis Raioni', +'GE-36' => 'Georgia: Martvilis Raioni', +'GE-37' => 'Georgia: Mestiis Raioni', +'GE-38' => 'Georgia: Mts\'khet\'is Raioni', +'GE-39' => 'Georgia: Ninotsmindis Raioni', +'GE-40' => 'Georgia: Onis Raioni', +'GE-41' => 'Georgia: Ozurget\'is Raioni', +'GE-42' => 'Georgia: P\'ot\'i', +'GE-43' => 'Georgia: Qazbegis Raioni', +'GE-44' => 'Georgia: Qvarlis Raioni', +'GE-45' => 'Georgia: Rust\'avi', +'GE-46' => 'Georgia: Sach\'kheris Raioni', +'GE-47' => 'Georgia: Sagarejos Raioni', +'GE-48' => 'Georgia: Samtrediis Raioni', +'GE-49' => 'Georgia: Senakis Raioni', +'GE-50' => 'Georgia: Sighnaghis Raioni', +'GE-51' => 'Georgia: T\'bilisi', +'GE-52' => 'Georgia: T\'elavis Raioni', +'GE-53' => 'Georgia: T\'erjolis Raioni', +'GE-54' => 'Georgia: T\'et\'ritsqaros Raioni', +'GE-55' => 'Georgia: T\'ianet\'is Raioni', +'GE-56' => 'Georgia: Tqibuli', +'GE-57' => 'Georgia: Ts\'ageris Raioni', +'GE-58' => 'Georgia: Tsalenjikhis Raioni', +'GE-59' => 'Georgia: Tsalkis Raioni', +'GE-60' => 'Georgia: Tsqaltubo', +'GE-61' => 'Georgia: Vanis Raioni', +'GE-62' => 'Georgia: Zestap\'onis Raioni', +'GE-63' => 'Georgia: Zugdidi', +'GE-64' => 'Georgia: Zugdidis Raioni', + +'--DE' => '','-DE' => 'Germany', +'DE-01' => 'Germany: Baden-Württemberg', +'DE-02' => 'Germany: Bayern', +'DE-16' => 'Germany: Berlin', +'DE-11' => 'Germany: Brandenburg', +'DE-03' => 'Germany: Bremen', +'DE-04' => 'Germany: Hamburg', +'DE-05' => 'Germany: Hessen', +'DE-12' => 'Germany: Mecklenburg-Vorpommern', +'DE-06' => 'Germany: Niedersachsen', +'DE-07' => 'Germany: Nordrhein-Westfalen', +'DE-08' => 'Germany: Rheinland-Pfalz', +'DE-09' => 'Germany: Saarland', +'DE-13' => 'Germany: Sachsen', +'DE-14' => 'Germany: Sachsen-Anhalt', +'DE-10' => 'Germany: Schleswig-Holstein', +'DE-15' => 'Germany: Thuringen', + +'--GH' => '','-GH' => 'Ghana', +'GH-02' => 'Ghana: Ashanti', +'GH-03' => 'Ghana: Brong-Ahafo', +'GH-04' => 'Ghana: Central', +'GH-05' => 'Ghana: Eastern', +'GH-01' => 'Ghana: Greater Accra', +'GH-06' => 'Ghana: Northern', +'GH-10' => 'Ghana: Upper East', +'GH-11' => 'Ghana: Upper West', +'GH-08' => 'Ghana: Volta', +'GH-09' => 'Ghana: Western', + +'--GR' => '','-GR' => 'Greece', +'GR-31' => 'Greece: Aitolia kai Akarnania', +'GR-38' => 'Greece: Akhaia', +'GR-36' => 'Greece: Argolis', +'GR-41' => 'Greece: Arkadhia', +'GR-20' => 'Greece: Arta', +'GR-35' => 'Greece: Attiki', +'GR-47' => 'Greece: Dhodhekanisos', +'GR-04' => 'Greece: Drama', +'GR-30' => 'Greece: Evritania', +'GR-01' => 'Greece: Evros', +'GR-34' => 'Greece: Evvoia', +'GR-08' => 'Greece: Florina', +'GR-32' => 'Greece: Fokis', +'GR-29' => 'Greece: Fthiotis', +'GR-10' => 'Greece: Grevena', +'GR-39' => 'Greece: Ilia', +'GR-12' => 'Greece: Imathia', +'GR-17' => 'Greece: Ioannina', +'GR-45' => 'Greece: Iraklion', +'GR-23' => 'Greece: Kardhitsa', +'GR-09' => 'Greece: Kastoria', +'GR-14' => 'Greece: Kavala', +'GR-27' => 'Greece: Kefallinia', +'GR-25' => 'Greece: Kerkira', +'GR-15' => 'Greece: Khalkidhiki', +'GR-43' => 'Greece: Khania', +'GR-50' => 'Greece: Khios', +'GR-49' => 'Greece: Kikladhes', +'GR-06' => 'Greece: Kilkis', +'GR-37' => 'Greece: Korinthia', +'GR-11' => 'Greece: Kozani', +'GR-42' => 'Greece: Lakonia', +'GR-21' => 'Greece: Larisa', +'GR-46' => 'Greece: Lasithi', +'GR-51' => 'Greece: Lesvos', +'GR-26' => 'Greece: Levkas', +'GR-24' => 'Greece: Magnisia', +'GR-40' => 'Greece: Messinia', +'GR-07' => 'Greece: Pella', +'GR-16' => 'Greece: Pieria', +'GR-19' => 'Greece: Preveza', +'GR-44' => 'Greece: Rethimni', +'GR-02' => 'Greece: Rodhopi', +'GR-48' => 'Greece: Samos', +'GR-05' => 'Greece: Serrai', +'GR-18' => 'Greece: Thesprotia', +'GR-13' => 'Greece: Thessaloniki', +'GR-22' => 'Greece: Trikala', +'GR-33' => 'Greece: Voiotia', +'GR-03' => 'Greece: Xanthi', +'GR-28' => 'Greece: Zakinthos', + +'--GL' => '','-GL' => 'Greenland', +'GL-01' => 'Greenland: Nordgronland', +'GL-02' => 'Greenland: Ostgronland', +'GL-03' => 'Greenland: Vestgronland', + +'--GD' => '','-GD' => 'Grenada', +'GD-01' => 'Grenada: Saint Andrew', +'GD-02' => 'Grenada: Saint David', +'GD-03' => 'Grenada: Saint George', +'GD-04' => 'Grenada: Saint John', +'GD-05' => 'Grenada: Saint Mark', +'GD-06' => 'Grenada: Saint Patrick', + +'--GT' => '','-GT' => 'Guatemala', +'GT-01' => 'Guatemala: Alta Verapaz', +'GT-02' => 'Guatemala: Baja Verapaz', +'GT-03' => 'Guatemala: Chimaltenango', +'GT-04' => 'Guatemala: Chiquimula', +'GT-05' => 'Guatemala: El Progreso', +'GT-06' => 'Guatemala: Escuintla', +'GT-07' => 'Guatemala: Guatemala', +'GT-08' => 'Guatemala: Huehuetenango', +'GT-09' => 'Guatemala: Izabal', +'GT-10' => 'Guatemala: Jalapa', +'GT-11' => 'Guatemala: Jutiapa', +'GT-12' => 'Guatemala: Peten', +'GT-13' => 'Guatemala: Quetzaltenango', +'GT-14' => 'Guatemala: Quiche', +'GT-15' => 'Guatemala: Retalhuleu', +'GT-16' => 'Guatemala: Sacatepequez', +'GT-17' => 'Guatemala: San Marcos', +'GT-18' => 'Guatemala: Santa Rosa', +'GT-19' => 'Guatemala: Solola', +'GT-20' => 'Guatemala: Suchitepequez', +'GT-21' => 'Guatemala: Totonicapan', +'GT-22' => 'Guatemala: Zacapa', + +'--GN' => '','-GN' => 'Guinea', +'GN-01' => 'Guinea: Beyla', +'GN-02' => 'Guinea: Boffa', +'GN-03' => 'Guinea: Boke', +'GN-04' => 'Guinea: Conakry', +'GN-30' => 'Guinea: Coyah', +'GN-05' => 'Guinea: Dabola', +'GN-06' => 'Guinea: Dalaba', +'GN-07' => 'Guinea: Dinguiraye', +'GN-31' => 'Guinea: Dubreka', +'GN-09' => 'Guinea: Faranah', +'GN-10' => 'Guinea: Forecariah', +'GN-11' => 'Guinea: Fria', +'GN-12' => 'Guinea: Gaoual', +'GN-13' => 'Guinea: Gueckedou', +'GN-32' => 'Guinea: Kankan', +'GN-15' => 'Guinea: Kerouane', +'GN-16' => 'Guinea: Kindia', +'GN-17' => 'Guinea: Kissidougou', +'GN-33' => 'Guinea: Koubia', +'GN-18' => 'Guinea: Koundara', +'GN-19' => 'Guinea: Kouroussa', +'GN-34' => 'Guinea: Labe', +'GN-35' => 'Guinea: Lelouma', +'GN-36' => 'Guinea: Lola', +'GN-21' => 'Guinea: Macenta', +'GN-22' => 'Guinea: Mali', +'GN-23' => 'Guinea: Mamou', +'GN-37' => 'Guinea: Mandiana', +'GN-38' => 'Guinea: Nzerekore', +'GN-25' => 'Guinea: Pita', +'GN-39' => 'Guinea: Siguiri', +'GN-27' => 'Guinea: Telimele', +'GN-28' => 'Guinea: Tougue', +'GN-29' => 'Guinea: Yomou', + +'--GW' => '','-GW' => 'Guinea-Bissau', +'GW-01' => 'Guinea-Bissau: Bafata', +'GW-12' => 'Guinea-Bissau: Biombo', +'GW-11' => 'Guinea-Bissau: Bissau', +'GW-05' => 'Guinea-Bissau: Bolama', +'GW-06' => 'Guinea-Bissau: Cacheu', +'GW-10' => 'Guinea-Bissau: Gabu', +'GW-04' => 'Guinea-Bissau: Oio', +'GW-02' => 'Guinea-Bissau: Quinara', +'GW-07' => 'Guinea-Bissau: Tombali', + +'--GY' => '','-GY' => 'Guyana', +'GY-10' => 'Guyana: Barima-Waini', +'GY-11' => 'Guyana: Cuyuni-Mazaruni', +'GY-12' => 'Guyana: Demerara-Mahaica', +'GY-13' => 'Guyana: East Berbice-Corentyne', +'GY-14' => 'Guyana: Essequibo Islands-West Demerara', +'GY-15' => 'Guyana: Mahaica-Berbice', +'GY-16' => 'Guyana: Pomeroon-Supenaam', +'GY-17' => 'Guyana: Potaro-Siparuni', +'GY-18' => 'Guyana: Upper Demerara-Berbice', +'GY-19' => 'Guyana: Upper Takutu-Upper Essequibo', + +'--HT' => '','-HT' => 'Haiti', +'HT-06' => 'Haiti: Artibonite', +'HT-07' => 'Haiti: Centre', +'HT-08' => 'Haiti: Grand\' Anse', +'HT-09' => 'Haiti: Nord', +'HT-10' => 'Haiti: Nord-Est', +'HT-03' => 'Haiti: Nord-Ouest', +'HT-11' => 'Haiti: Ouest', +'HT-12' => 'Haiti: Sud', +'HT-13' => 'Haiti: Sud-Est', + +'--HN' => '','-HN' => 'Honduras', +'HN-01' => 'Honduras: Atlantida', +'HN-02' => 'Honduras: Choluteca', +'HN-03' => 'Honduras: Colon', +'HN-04' => 'Honduras: Comayagua', +'HN-05' => 'Honduras: Copan', +'HN-06' => 'Honduras: Cortes', +'HN-07' => 'Honduras: El Paraiso', +'HN-08' => 'Honduras: Francisco Morazan', +'HN-09' => 'Honduras: Gracias a Dios', +'HN-10' => 'Honduras: Intibuca', +'HN-11' => 'Honduras: Islas de la Bahia', +'HN-12' => 'Honduras: La Paz', +'HN-13' => 'Honduras: Lempira', +'HN-14' => 'Honduras: Ocotepeque', +'HN-15' => 'Honduras: Olancho', +'HN-16' => 'Honduras: Santa Barbara', +'HN-17' => 'Honduras: Valle', +'HN-18' => 'Honduras: Yoro', + +'--HU' => '','-HU' => 'Hungary', +'HU-01' => 'Hungary: Bacs-Kiskun', +'HU-02' => 'Hungary: Baranya', +'HU-03' => 'Hungary: Bekes', +'HU-26' => 'Hungary: Bekescsaba', +'HU-04' => 'Hungary: Borsod-Abauj-Zemplen', +'HU-05' => 'Hungary: Budapest', +'HU-06' => 'Hungary: Csongrad', +'HU-07' => 'Hungary: Debrecen', +'HU-27' => 'Hungary: Dunaujvaros', +'HU-28' => 'Hungary: Eger', +'HU-08' => 'Hungary: Fejer', +'HU-25' => 'Hungary: Gyor', +'HU-09' => 'Hungary: Gyor-Moson-Sopron', +'HU-10' => 'Hungary: Hajdu-Bihar', +'HU-11' => 'Hungary: Heves', +'HU-29' => 'Hungary: Hodmezovasarhely', +'HU-20' => 'Hungary: Jasz-Nagykun-Szolnok', +'HU-30' => 'Hungary: Kaposvar', +'HU-31' => 'Hungary: Kecskemet', +'HU-12' => 'Hungary: Komarom-Esztergom', +'HU-13' => 'Hungary: Miskolc', +'HU-32' => 'Hungary: Nagykanizsa', +'HU-14' => 'Hungary: Nograd', +'HU-33' => 'Hungary: Nyiregyhaza', +'HU-15' => 'Hungary: Pecs', +'HU-16' => 'Hungary: Pest', +'HU-17' => 'Hungary: Somogy', +'HU-34' => 'Hungary: Sopron', +'HU-18' => 'Hungary: Szabolcs-Szatmar-Bereg', +'HU-19' => 'Hungary: Szeged', +'HU-35' => 'Hungary: Szekesfehervar', +'HU-36' => 'Hungary: Szolnok', +'HU-37' => 'Hungary: Szombathely', +'HU-38' => 'Hungary: Tatabanya', +'HU-21' => 'Hungary: Tolna', +'HU-22' => 'Hungary: Vas', +'HU-23' => 'Hungary: Veszprem', +'HU-39' => 'Hungary: Veszprem', +'HU-24' => 'Hungary: Zala', +'HU-40' => 'Hungary: Zalaegerszeg', + +'--IS' => '','-IS' => 'Iceland', +'IS-01' => 'Iceland: Akranes', +'IS-02' => 'Iceland: Akureyri', +'IS-03' => 'Iceland: Arnessysla', +'IS-04' => 'Iceland: Austur-Bardastrandarsysla', +'IS-05' => 'Iceland: Austur-Hunavatnssysla', +'IS-06' => 'Iceland: Austur-Skaftafellssysla', +'IS-07' => 'Iceland: Borgarfjardarsysla', +'IS-08' => 'Iceland: Dalasysla', +'IS-09' => 'Iceland: Eyjafjardarsysla', +'IS-10' => 'Iceland: Gullbringusysla', +'IS-11' => 'Iceland: Hafnarfjordur', +'IS-12' => 'Iceland: Husavik', +'IS-13' => 'Iceland: Isafjordur', +'IS-14' => 'Iceland: Keflavik', +'IS-15' => 'Iceland: Kjosarsysla', +'IS-16' => 'Iceland: Kopavogur', +'IS-17' => 'Iceland: Myrasysla', +'IS-18' => 'Iceland: Neskaupstadur', +'IS-19' => 'Iceland: Nordur-Isafjardarsysla', +'IS-20' => 'Iceland: Nordur-Mulasysla', +'IS-21' => 'Iceland: Nordur-Tingeyjarsysla', +'IS-22' => 'Iceland: Olafsfjordur', +'IS-23' => 'Iceland: Rangarvallasysla', +'IS-24' => 'Iceland: Reykjavik', +'IS-25' => 'Iceland: Saudarkrokur', +'IS-26' => 'Iceland: Seydisfjordur', +'IS-27' => 'Iceland: Siglufjordur', +'IS-28' => 'Iceland: Skagafjardarsysla', +'IS-29' => 'Iceland: Snafellsnes- og Hnappadalssysla', +'IS-30' => 'Iceland: Strandasysla', +'IS-31' => 'Iceland: Sudur-Mulasysla', +'IS-32' => 'Iceland: Sudur-Tingeyjarsysla', +'IS-33' => 'Iceland: Vestmannaeyjar', +'IS-34' => 'Iceland: Vestur-Bardastrandarsysla', +'IS-35' => 'Iceland: Vestur-Hunavatnssysla', +'IS-36' => 'Iceland: Vestur-Isafjardarsysla', +'IS-37' => 'Iceland: Vestur-Skaftafellssysla', + +'--IN' => '','-IN' => 'India', +'IN-01' => 'India: Andaman and Nicobar Islands', +'IN-02' => 'India: Andhra Pradesh', +'IN-30' => 'India: Arunachal Pradesh', +'IN-03' => 'India: Assam', +'IN-34' => 'India: Bihar', +'IN-05' => 'India: Chandigarh', +'IN-37' => 'India: Chhattisgarh', +'IN-06' => 'India: Dadra and Nagar Haveli', +'IN-32' => 'India: Daman and Diu', +'IN-07' => 'India: Delhi', +'IN-33' => 'India: Goa', +'IN-09' => 'India: Gujarat', +'IN-10' => 'India: Haryana', +'IN-11' => 'India: Himachal Pradesh', +'IN-12' => 'India: Jammu and Kashmir', +'IN-38' => 'India: Jharkhand', +'IN-19' => 'India: Karnataka', +'IN-13' => 'India: Kerala', +'IN-14' => 'India: Lakshadweep', +'IN-35' => 'India: Madhya Pradesh', +'IN-16' => 'India: Maharashtra', +'IN-17' => 'India: Manipur', +'IN-18' => 'India: Meghalaya', +'IN-31' => 'India: Mizoram', +'IN-20' => 'India: Nagaland', +'IN-21' => 'India: Orissa', +'IN-22' => 'India: Pondicherry', +'IN-23' => 'India: Punjab', +'IN-24' => 'India: Rajasthan', +'IN-29' => 'India: Sikkim', +'IN-25' => 'India: Tamil Nadu', +'IN-26' => 'India: Tripura', +'IN-36' => 'India: Uttar Pradesh', +'IN-39' => 'India: Uttaranchal', +'IN-28' => 'India: West Bengal', + +'--ID' => '','-ID' => 'Indonesia', +'ID-01' => 'Indonesia: Aceh', +'ID-02' => 'Indonesia: Bali', +'ID-33' => 'Indonesia: Banten', +'ID-03' => 'Indonesia: Bengkulu', +'ID-34' => 'Indonesia: Gorontalo', +'ID-04' => 'Indonesia: Jakarta Raya', +'ID-05' => 'Indonesia: Jambi', +'ID-30' => 'Indonesia: Jawa Barat', +'ID-07' => 'Indonesia: Jawa Tengah', +'ID-08' => 'Indonesia: Jawa Timur', +'ID-11' => 'Indonesia: Kalimantan Barat', +'ID-12' => 'Indonesia: Kalimantan Selatan', +'ID-13' => 'Indonesia: Kalimantan Tengah', +'ID-14' => 'Indonesia: Kalimantan Timur', +'ID-35' => 'Indonesia: Kepulauan Bangka Belitung', +'ID-15' => 'Indonesia: Lampung', +'ID-29' => 'Indonesia: Maluku Utara', +'ID-28' => 'Indonesia: Maluku', +'ID-17' => 'Indonesia: Nusa Tenggara Barat', +'ID-18' => 'Indonesia: Nusa Tenggara Timur', +'ID-09' => 'Indonesia: Papua', +'ID-19' => 'Indonesia: Riau', +'ID-20' => 'Indonesia: Sulawesi Selatan', +'ID-21' => 'Indonesia: Sulawesi Tengah', +'ID-22' => 'Indonesia: Sulawesi Tenggara', +'ID-31' => 'Indonesia: Sulawesi Utara', +'ID-24' => 'Indonesia: Sumatera Barat', +'ID-25' => 'Indonesia: Sumatera Selatan', +'ID-32' => 'Indonesia: Sumatera Selatan', +'ID-26' => 'Indonesia: Sumatera Utara', +'ID-10' => 'Indonesia: Yogyakarta', + +'--IR' => '','-IR' => 'Iran', +'IR-32' => 'Iran: Ardabil', +'IR-01' => 'Iran: Azarbayjan-e Bakhtari', +'IR-02' => 'Iran: Azarbayjan-e Khavari', +'IR-13' => 'Iran: Bakhtaran', +'IR-22' => 'Iran: Bushehr', +'IR-03' => 'Iran: Chahar Mahall va Bakhtiari', +'IR-28' => 'Iran: Esfahan', +'IR-07' => 'Iran: Fars', +'IR-08' => 'Iran: Gilan', +'IR-37' => 'Iran: Golestan', +'IR-09' => 'Iran: Hamadan', +'IR-11' => 'Iran: Hormozgan', +'IR-10' => 'Iran: Ilam', +'IR-29' => 'Iran: Kerman', +'IR-30' => 'Iran: Khorasan', +'IR-15' => 'Iran: Khuzestan', +'IR-05' => 'Iran: Kohkiluyeh va Buyer Ahmadi', +'IR-16' => 'Iran: Kordestan', +'IR-23' => 'Iran: Lorestan', +'IR-34' => 'Iran: Markazi', +'IR-35' => 'Iran: Mazandaran', +'IR-38' => 'Iran: Qazvin', +'IR-39' => 'Iran: Qom', +'IR-25' => 'Iran: Semnan', +'IR-04' => 'Iran: Sistan va Baluchestan', +'IR-26' => 'Iran: Tehran', +'IR-31' => 'Iran: Yazd', +'IR-36' => 'Iran: Zanjan', + +'--IQ' => '','-IQ' => 'Iraq', +'IQ-01' => 'Iraq: Al Anbar', +'IQ-02' => 'Iraq: Al Basrah', +'IQ-03' => 'Iraq: Al Muthanna', +'IQ-04' => 'Iraq: Al Qadisiyah', +'IQ-17' => 'Iraq: An Najaf', +'IQ-11' => 'Iraq: Arbil', +'IQ-05' => 'Iraq: As Sulaymaniyah', +'IQ-13' => 'Iraq: At Ta\'mim', +'IQ-06' => 'Iraq: Babil', +'IQ-07' => 'Iraq: Baghdad', +'IQ-08' => 'Iraq: Dahuk', +'IQ-09' => 'Iraq: Dhi Qar', +'IQ-10' => 'Iraq: Diyala', +'IQ-12' => 'Iraq: Karbala\'', +'IQ-14' => 'Iraq: Maysan', +'IQ-15' => 'Iraq: Ninawa', +'IQ-18' => 'Iraq: Salah ad Din', +'IQ-16' => 'Iraq: Wasit', + +'--IE' => '','-IE' => 'Ireland', +'IE-01' => 'Ireland: Carlow', +'IE-02' => 'Ireland: Cavan', +'IE-03' => 'Ireland: Clare', +'IE-04' => 'Ireland: Cork', +'IE-06' => 'Ireland: Donegal', +'IE-07' => 'Ireland: Dublin', +'IE-10' => 'Ireland: Galway', +'IE-11' => 'Ireland: Kerry', +'IE-12' => 'Ireland: Kildare', +'IE-13' => 'Ireland: Kilkenny', +'IE-15' => 'Ireland: Laois', +'IE-14' => 'Ireland: Leitrim', +'IE-16' => 'Ireland: Limerick', +'IE-18' => 'Ireland: Longford', +'IE-19' => 'Ireland: Louth', +'IE-20' => 'Ireland: Mayo', +'IE-21' => 'Ireland: Meath', +'IE-22' => 'Ireland: Monaghan', +'IE-23' => 'Ireland: Offaly', +'IE-24' => 'Ireland: Roscommon', +'IE-25' => 'Ireland: Sligo', +'IE-26' => 'Ireland: Tipperary', +'IE-27' => 'Ireland: Waterford', +'IE-29' => 'Ireland: Westmeath', +'IE-30' => 'Ireland: Wexford', +'IE-31' => 'Ireland: Wicklow', + +'--IL' => '','-IL' => 'Israel', +'IL-01' => 'Israel: HaDarom', +'IL-02' => 'Israel: HaMerkaz', +'IL-03' => 'Israel: HaZafon', +'IL-04' => 'Israel: Hefa', +'IL-05' => 'Israel: Tel Aviv', +'IL-06' => 'Israel: Yerushalayim', + +'--IT' => '','-IT' => 'Italy', +'IT-01' => 'Italy: Abruzzi', +'IT-02' => 'Italy: Basilicata', +'IT-03' => 'Italy: Calabria', +'IT-04' => 'Italy: Campania', +'IT-05' => 'Italy: Emilia-Romagna', +'IT-06' => 'Italy: Friuli-Venezia Giulia', +'IT-07' => 'Italy: Lazio', +'IT-08' => 'Italy: Liguria', +'IT-09' => 'Italy: Lombardia', +'IT-10' => 'Italy: Marche', +'IT-11' => 'Italy: Molise', +'IT-12' => 'Italy: Piemonte', +'IT-13' => 'Italy: Puglia', +'IT-14' => 'Italy: Sardegna', +'IT-15' => 'Italy: Sicilia', +'IT-16' => 'Italy: Toscana', +'IT-17' => 'Italy: Trentino-Alto Adige', +'IT-18' => 'Italy: Umbria', +'IT-19' => 'Italy: Valle d\'Aosta', +'IT-20' => 'Italy: Veneto', + +'--JM' => '','-JM' => 'Jamaica', +'JM-01' => 'Jamaica: Clarendon', +'JM-02' => 'Jamaica: Hanover', +'JM-17' => 'Jamaica: Kingston', +'JM-04' => 'Jamaica: Manchester', +'JM-07' => 'Jamaica: Portland', +'JM-08' => 'Jamaica: Saint Andrew', +'JM-09' => 'Jamaica: Saint Ann', +'JM-10' => 'Jamaica: Saint Catherine', +'JM-11' => 'Jamaica: Saint Elizabeth', +'JM-12' => 'Jamaica: Saint James', +'JM-13' => 'Jamaica: Saint Mary', +'JM-14' => 'Jamaica: Saint Thomas', +'JM-15' => 'Jamaica: Trelawny', +'JM-16' => 'Jamaica: Westmoreland', + +'--JP' => '','-JP' => 'Japan', +'JP-01' => 'Japan: Aichi', +'JP-02' => 'Japan: Akita', +'JP-03' => 'Japan: Aomori', +'JP-04' => 'Japan: Chiba', +'JP-05' => 'Japan: Ehime', +'JP-06' => 'Japan: Fukui', +'JP-07' => 'Japan: Fukuoka', +'JP-08' => 'Japan: Fukushima', +'JP-09' => 'Japan: Gifu', +'JP-10' => 'Japan: Gumma', +'JP-11' => 'Japan: Hiroshima', +'JP-12' => 'Japan: Hokkaido', +'JP-13' => 'Japan: Hyogo', +'JP-14' => 'Japan: Ibaraki', +'JP-15' => 'Japan: Ishikawa', +'JP-16' => 'Japan: Iwate', +'JP-17' => 'Japan: Kagawa', +'JP-18' => 'Japan: Kagoshima', +'JP-19' => 'Japan: Kanagawa', +'JP-20' => 'Japan: Kochi', +'JP-21' => 'Japan: Kumamoto', +'JP-22' => 'Japan: Kyoto', +'JP-23' => 'Japan: Mie', +'JP-24' => 'Japan: Miyagi', +'JP-25' => 'Japan: Miyazaki', +'JP-26' => 'Japan: Nagano', +'JP-27' => 'Japan: Nagasaki', +'JP-28' => 'Japan: Nara', +'JP-29' => 'Japan: Niigata', +'JP-30' => 'Japan: Oita', +'JP-31' => 'Japan: Okayama', +'JP-47' => 'Japan: Okinawa', +'JP-32' => 'Japan: Osaka', +'JP-33' => 'Japan: Saga', +'JP-34' => 'Japan: Saitama', +'JP-35' => 'Japan: Shiga', +'JP-36' => 'Japan: Shimane', +'JP-37' => 'Japan: Shizuoka', +'JP-38' => 'Japan: Tochigi', +'JP-39' => 'Japan: Tokushima', +'JP-40' => 'Japan: Tokyo', +'JP-41' => 'Japan: Tottori', +'JP-42' => 'Japan: Toyama', +'JP-43' => 'Japan: Wakayama', +'JP-44' => 'Japan: Yamagata', +'JP-45' => 'Japan: Yamaguchi', +'JP-46' => 'Japan: Yamanashi', + +'--JO' => '','-JO' => 'Jordan', +'JO-02' => 'Jordan: Al Balqa\'', +'JO-09' => 'Jordan: Al Karak', +'JO-10' => 'Jordan: Al Mafraq', +'JO-16' => 'Jordan: Amman', +'JO-12' => 'Jordan: At Tafilah', +'JO-13' => 'Jordan: Az Zarqa', +'JO-14' => 'Jordan: Irbid', +'JO-07' => 'Jordan: Ma', + +'--KZ' => '','-KZ' => 'Kazakhstan', +'KZ-02' => 'Kazakhstan: Almaty City', +'KZ-01' => 'Kazakhstan: Almaty', +'KZ-03' => 'Kazakhstan: Aqmola', +'KZ-04' => 'Kazakhstan: Aqt?be', +'KZ-05' => 'Kazakhstan: Astana', +'KZ-06' => 'Kazakhstan: Atyrau', +'KZ-08' => 'Kazakhstan: Bayqonyr', +'KZ-15' => 'Kazakhstan: East Kazakhstan', +'KZ-09' => 'Kazakhstan: Mangghystau', +'KZ-16' => 'Kazakhstan: North Kazakhstan', +'KZ-11' => 'Kazakhstan: Pavlodar', +'KZ-12' => 'Kazakhstan: Qaraghandy', +'KZ-13' => 'Kazakhstan: Qostanay', +'KZ-14' => 'Kazakhstan: Qyzylorda', +'KZ-10' => 'Kazakhstan: South Kazakhstan', +'KZ-07' => 'Kazakhstan: West Kazakhstan', +'KZ-17' => 'Kazakhstan: Zhambyl', + +'--KE' => '','-KE' => 'Kenya', +'KE-01' => 'Kenya: Central', +'KE-02' => 'Kenya: Coast', +'KE-03' => 'Kenya: Eastern', +'KE-05' => 'Kenya: Nairobi Area', +'KE-06' => 'Kenya: North-Eastern', +'KE-07' => 'Kenya: Nyanza', +'KE-08' => 'Kenya: Rift Valley', +'KE-09' => 'Kenya: Western', + +'--KI' => '','-KI' => 'Kiribati', +'KI-01' => 'Kiribati: Gilbert Islands', +'KI-02' => 'Kiribati: Line Islands', +'KI-03' => 'Kiribati: Phoenix Islands', + +'--KW' => '','-KW' => 'Kuwait', +'KW-01' => 'Kuwait: Al Ahmadi', +'KW-05' => 'Kuwait: Al Jahra', +'KW-02' => 'Kuwait: Al Kuwayt', +'KW-03' => 'Kuwait: Hawalli', + +'--KG' => '','-KG' => 'Kyrgyzstan', +'KG-09' => 'Kyrgyzstan: Batken', +'KG-01' => 'Kyrgyzstan: Bishkek', +'KG-02' => 'Kyrgyzstan: Chuy', +'KG-03' => 'Kyrgyzstan: Jalal-Abad', +'KG-04' => 'Kyrgyzstan: Naryn', +'KG-08' => 'Kyrgyzstan: Osh', +'KG-06' => 'Kyrgyzstan: Talas', +'KG-07' => 'Kyrgyzstan: Ysyk-Kol', + +'--LA' => '','-LA' => 'Lao', +'LA-01' => 'Lao: Attapu', +'LA-02' => 'Lao: Champasak', +'LA-03' => 'Lao: Houaphan', +'LA-04' => 'Lao: Khammouan', +'LA-05' => 'Lao: Louang Namtha', +'LA-17' => 'Lao: Louangphrabang', +'LA-07' => 'Lao: Oudomxai', +'LA-08' => 'Lao: Phongsali', +'LA-09' => 'Lao: Saravan', +'LA-10' => 'Lao: Savannakhet', +'LA-11' => 'Lao: Vientiane', +'LA-13' => 'Lao: Xaignabouri', +'LA-14' => 'Lao: Xiangkhoang', + +'--LV' => '','-LV' => 'Latvia', +'LV-01' => 'Latvia: Aizkraukles', +'LV-02' => 'Latvia: Aluksnes', +'LV-03' => 'Latvia: Balvu', +'LV-04' => 'Latvia: Bauskas', +'LV-05' => 'Latvia: Césu', +'LV-06' => 'Latvia: Daugavpils', +'LV-07' => 'Latvia: Daugavpils', +'LV-08' => 'Latvia: Dobeles', +'LV-09' => 'Latvia: Gulbenes', +'LV-10' => 'Latvia: Jékabpils', +'LV-11' => 'Latvia: Jelgava', +'LV-12' => 'Latvia: Jelgavas', +'LV-13' => 'Latvia: Jurmala', +'LV-14' => 'Latvia: Kráslavas', +'LV-15' => 'Latvia: Kuldigas', +'LV-16' => 'Latvia: Liepája', +'LV-17' => 'Latvia: Liepájas', +'LV-18' => 'Latvia: Limbazu', +'LV-19' => 'Latvia: Ludzas', +'LV-20' => 'Latvia: Madonas', +'LV-21' => 'Latvia: Ogres', +'LV-22' => 'Latvia: Preilu', +'LV-23' => 'Latvia: Rézekne', +'LV-24' => 'Latvia: Rézeknes', +'LV-25' => 'Latvia: Riga', +'LV-26' => 'Latvia: Rigas', +'LV-27' => 'Latvia: Saldus', +'LV-28' => 'Latvia: Talsu', +'LV-29' => 'Latvia: Tukuma', +'LV-30' => 'Latvia: Valkas', +'LV-31' => 'Latvia: Valmieras', +'LV-32' => 'Latvia: Ventspils', +'LV-33' => 'Latvia: Ventspils', + +'--LB' => '','-LB' => 'Lebanon', +'LB-01' => 'Lebanon: Beqaa', +'LB-04' => 'Lebanon: Beyrouth', +'LB-03' => 'Lebanon: Liban-Nord', +'LB-06' => 'Lebanon: Liban-Sud', +'LB-05' => 'Lebanon: Mont-Liban', +'LB-07' => 'Lebanon: Nabatiye', + +'--LS' => '','-LS' => 'Lesotho', +'LS-10' => 'Lesotho: Berea', +'LS-11' => 'Lesotho: Butha-Buthe', +'LS-12' => 'Lesotho: Leribe', +'LS-13' => 'Lesotho: Mafeteng', +'LS-14' => 'Lesotho: Maseru', +'LS-15' => 'Lesotho: Mohales Hoek', +'LS-16' => 'Lesotho: Mokhotlong', +'LS-17' => 'Lesotho: Qachas Nek', +'LS-18' => 'Lesotho: Quthing', +'LS-19' => 'Lesotho: Thaba-Tseka', + +'--LR' => '','-LR' => 'Liberia', +'LR-01' => 'Liberia: Bong', +'LR-11' => 'Liberia: Grand Bassa', +'LR-04' => 'Liberia: Grand Cape Mount', +'LR-02' => 'Liberia: Grand Jide', +'LR-05' => 'Liberia: Lofa', +'LR-06' => 'Liberia: Maryland', +'LR-07' => 'Liberia: Monrovia', +'LR-14' => 'Liberia: Montserrado', +'LR-09' => 'Liberia: Nimba', +'LR-10' => 'Liberia: Sino', + +'--LY' => '','-LY' => 'Libyan Arab Jamahiriya', +'LY-47' => 'Libyan Arab Jamahiriya: Ajdabiya', +'LY-48' => 'Libyan Arab Jamahiriya: Al Fatih', +'LY-49' => 'Libyan Arab Jamahiriya: Al Jabal al Akhdar', +'LY-05' => 'Libyan Arab Jamahiriya: Al Jufrah', +'LY-50' => 'Libyan Arab Jamahiriya: Al Khums', +'LY-08' => 'Libyan Arab Jamahiriya: Al Kufrah', +'LY-03' => 'Libyan Arab Jamahiriya: Al', +'LY-51' => 'Libyan Arab Jamahiriya: An Nuqat al Khams', +'LY-13' => 'Libyan Arab Jamahiriya: Ash Shati\'', +'LY-52' => 'Libyan Arab Jamahiriya: Awbari', +'LY-53' => 'Libyan Arab Jamahiriya: Az Zawiyah', +'LY-54' => 'Libyan Arab Jamahiriya: Banghazi', +'LY-55' => 'Libyan Arab Jamahiriya: Darnah', +'LY-56' => 'Libyan Arab Jamahiriya: Ghadamis', +'LY-57' => 'Libyan Arab Jamahiriya: Gharyan', +'LY-58' => 'Libyan Arab Jamahiriya: Misratah', +'LY-30' => 'Libyan Arab Jamahiriya: Murzuq', +'LY-34' => 'Libyan Arab Jamahiriya: Sabha', +'LY-59' => 'Libyan Arab Jamahiriya: Sawfajjin', +'LY-60' => 'Libyan Arab Jamahiriya: Surt', +'LY-61' => 'Libyan Arab Jamahiriya: Tarabulus', +'LY-41' => 'Libyan Arab Jamahiriya: Tarhunah', +'LY-42' => 'Libyan Arab Jamahiriya: Tubruq', +'LY-62' => 'Libyan Arab Jamahiriya: Yafran', +'LY-45' => 'Libyan Arab Jamahiriya: Zlitan', + +'--LI' => '','-LI' => 'Liechtenstein', +'LI-01' => 'Liechtenstein: Balzers', +'LI-02' => 'Liechtenstein: Eschen', +'LI-03' => 'Liechtenstein: Gamprin', +'LI-04' => 'Liechtenstein: Mauren', +'LI-05' => 'Liechtenstein: Planken', +'LI-06' => 'Liechtenstein: Ruggell', +'LI-07' => 'Liechtenstein: Schaan', +'LI-08' => 'Liechtenstein: Schellenberg', +'LI-09' => 'Liechtenstein: Triesen', +'LI-10' => 'Liechtenstein: Triesenberg', +'LI-11' => 'Liechtenstein: Vaduz', + +'--LT' => '','-LT' => 'Lithuania', +'LT-56' => 'Lithuania: Alytaus Apskritis', +'LT-57' => 'Lithuania: Kauno Apskritis', +'LT-58' => 'Lithuania: Klaipedos Apskritis', +'LT-59' => 'Lithuania: Marijampoles Apskritis', +'LT-60' => 'Lithuania: Panevezio Apskritis', +'LT-61' => 'Lithuania: Siauliu Apskritis', +'LT-62' => 'Lithuania: Taurages Apskritis', +'LT-63' => 'Lithuania: Telsiu Apskritis', +'LT-64' => 'Lithuania: Utenos Apskritis', +'LT-65' => 'Lithuania: Vilniaus Apskritis', + +'--LU' => '','-LU' => 'Luxembourg', +'LU-01' => 'Luxembourg: Diekirch', +'LU-02' => 'Luxembourg: Grevenmacher', +'LU-03' => 'Luxembourg: Luxembourg', + +'--MO' => '','-MO' => 'Macau', +'MO-01' => 'Macau: Ilhas', +'MO-02' => 'Macau: Macau', + +'--MK' => '','-MK' => 'Macedonia', +'MK-01' => 'Macedonia: Aracinovo', +'MK-02' => 'Macedonia: Bac', +'MK-03' => 'Macedonia: Belcista', +'MK-04' => 'Macedonia: Berovo', +'MK-05' => 'Macedonia: Bistrica', +'MK-06' => 'Macedonia: Bitola', +'MK-07' => 'Macedonia: Blatec', +'MK-08' => 'Macedonia: Bogdanci', +'MK-09' => 'Macedonia: Bogomila', +'MK-10' => 'Macedonia: Bogovinje', +'MK-11' => 'Macedonia: Bosilovo', +'MK-12' => 'Macedonia: Brvenica', +'MK-13' => 'Macedonia: Cair', +'MK-14' => 'Macedonia: Capari', +'MK-15' => 'Macedonia: Caska', +'MK-16' => 'Macedonia: Cegrane', +'MK-18' => 'Macedonia: Centar Zupa', +'MK-17' => 'Macedonia: Centar', +'MK-19' => 'Macedonia: Cesinovo', +'MK-20' => 'Macedonia: Cucer-Sandevo', +'MK-21' => 'Macedonia: Debar', +'MK-22' => 'Macedonia: Delcevo', +'MK-23' => 'Macedonia: Delogozdi', +'MK-24' => 'Macedonia: Demir Hisar', +'MK-25' => 'Macedonia: Demir Kapija', +'MK-26' => 'Macedonia: Dobrusevo', +'MK-27' => 'Macedonia: Dolna Banjica', +'MK-28' => 'Macedonia: Dolneni', +'MK-29' => 'Macedonia: Dorce Petrov', +'MK-30' => 'Macedonia: Drugovo', +'MK-31' => 'Macedonia: Dzepciste', +'MK-32' => 'Macedonia: Gazi Baba', +'MK-33' => 'Macedonia: Gevgelija', +'MK-34' => 'Macedonia: Gostivar', +'MK-35' => 'Macedonia: Gradsko', +'MK-36' => 'Macedonia: Ilinden', +'MK-37' => 'Macedonia: Izvor', +'MK-38' => 'Macedonia: Jegunovce', +'MK-39' => 'Macedonia: Kamenjane', +'MK-40' => 'Macedonia: Karbinci', +'MK-41' => 'Macedonia: Karpos', +'MK-42' => 'Macedonia: Kavadarci', +'MK-43' => 'Macedonia: Kicevo', +'MK-44' => 'Macedonia: Kisela Voda', +'MK-45' => 'Macedonia: Klecevce', +'MK-46' => 'Macedonia: Kocani', +'MK-47' => 'Macedonia: Konce', +'MK-48' => 'Macedonia: Kondovo', +'MK-49' => 'Macedonia: Konopiste', +'MK-50' => 'Macedonia: Kosel', +'MK-51' => 'Macedonia: Kratovo', +'MK-52' => 'Macedonia: Kriva Palanka', +'MK-53' => 'Macedonia: Krivogastani', +'MK-54' => 'Macedonia: Krusevo', +'MK-55' => 'Macedonia: Kuklis', +'MK-56' => 'Macedonia: Kukurecani', +'MK-57' => 'Macedonia: Kumanovo', +'MK-58' => 'Macedonia: Labunista', +'MK-59' => 'Macedonia: Lipkovo', +'MK-60' => 'Macedonia: Lozovo', +'MK-61' => 'Macedonia: Lukovo', +'MK-62' => 'Macedonia: Makedonska Kamenica', +'MK-63' => 'Macedonia: Makedonski Brod', +'MK-64' => 'Macedonia: Mavrovi Anovi', +'MK-65' => 'Macedonia: Meseista', +'MK-66' => 'Macedonia: Miravci', +'MK-67' => 'Macedonia: Mogila', +'MK-68' => 'Macedonia: Murtino', +'MK-69' => 'Macedonia: Negotino', +'MK-70' => 'Macedonia: Negotino-Polosko', +'MK-71' => 'Macedonia: Novaci', +'MK-72' => 'Macedonia: Novo Selo', +'MK-73' => 'Macedonia: Oblesevo', +'MK-74' => 'Macedonia: Ohrid', +'MK-75' => 'Macedonia: Orasac', +'MK-76' => 'Macedonia: Orizari', +'MK-77' => 'Macedonia: Oslomej', +'MK-78' => 'Macedonia: Pehcevo', +'MK-79' => 'Macedonia: Petrovec', +'MK-80' => 'Macedonia: Plasnica', +'MK-81' => 'Macedonia: Podares', +'MK-82' => 'Macedonia: Prilep', +'MK-83' => 'Macedonia: Probistip', +'MK-84' => 'Macedonia: Radovis', +'MK-85' => 'Macedonia: Rankovce', +'MK-86' => 'Macedonia: Resen', +'MK-87' => 'Macedonia: Rosoman', +'MK-88' => 'Macedonia: Rostusa', +'MK-89' => 'Macedonia: Samokov', +'MK-90' => 'Macedonia: Saraj', +'MK-91' => 'Macedonia: Sipkovica', +'MK-92' => 'Macedonia: Sopiste', +'MK-93' => 'Macedonia: Sopotnica', +'MK-94' => 'Macedonia: Srbinovo', +'MK-96' => 'Macedonia: Star Dojran', +'MK-95' => 'Macedonia: Staravina', +'MK-97' => 'Macedonia: Staro Nagoricane', +'MK-98' => 'Macedonia: Stip', +'MK-99' => 'Macedonia: Struga', +'MK-A1' => 'Macedonia: Strumica', +'MK-A2' => 'Macedonia: Studenicani', +'MK-A3' => 'Macedonia: Suto Orizari', +'MK-A4' => 'Macedonia: Sveti Nikole', +'MK-A5' => 'Macedonia: Tearce', +'MK-A6' => 'Macedonia: Tetovo', +'MK-A7' => 'Macedonia: Topolcani', +'MK-A8' => 'Macedonia: Valandovo', +'MK-A9' => 'Macedonia: Vasilevo', +'MK-B1' => 'Macedonia: Veles', +'MK-B2' => 'Macedonia: Velesta', +'MK-B3' => 'Macedonia: Vevcani', +'MK-B4' => 'Macedonia: Vinica', +'MK-B5' => 'Macedonia: Vitoliste', +'MK-B6' => 'Macedonia: Vranestica', +'MK-B7' => 'Macedonia: Vrapciste', +'MK-B8' => 'Macedonia: Vratnica', +'MK-B9' => 'Macedonia: Vrutok', +'MK-C1' => 'Macedonia: Zajas', +'MK-C2' => 'Macedonia: Zelenikovo', +'MK-C3' => 'Macedonia: Zelino', +'MK-C4' => 'Macedonia: Zitose', +'MK-C5' => 'Macedonia: Zletovo', +'MK-C6' => 'Macedonia: Zrnovci', + +'--MG' => '','-MG' => 'Madagascar', +'MG-05' => 'Madagascar: Antananarivo', +'MG-01' => 'Madagascar: Antsiranana', +'MG-02' => 'Madagascar: Fianarantsoa', +'MG-03' => 'Madagascar: Mahajanga', +'MG-04' => 'Madagascar: Toamasina', +'MG-06' => 'Madagascar: Toliara', + +'--MW' => '','-MW' => 'Malawi', +'MW-26' => 'Malawi: Balaka', +'MW-24' => 'Malawi: Blantyre', +'MW-02' => 'Malawi: Chikwawa', +'MW-03' => 'Malawi: Chiradzulu', +'MW-04' => 'Malawi: Chitipa', +'MW-06' => 'Malawi: Dedza', +'MW-07' => 'Malawi: Dowa', +'MW-08' => 'Malawi: Karonga', +'MW-09' => 'Malawi: Kasungu', +'MW-27' => 'Malawi: Likoma', +'MW-11' => 'Malawi: Lilongwe', +'MW-28' => 'Malawi: Machinga', +'MW-12' => 'Malawi: Mangochi', +'MW-13' => 'Malawi: Mchinji', +'MW-29' => 'Malawi: Mulanje', +'MW-25' => 'Malawi: Mwanza', +'MW-15' => 'Malawi: Mzimba', +'MW-17' => 'Malawi: Nkhata Bay', +'MW-18' => 'Malawi: Nkhotakota', +'MW-19' => 'Malawi: Nsanje', +'MW-16' => 'Malawi: Ntcheu', +'MW-20' => 'Malawi: Ntchisi', +'MW-30' => 'Malawi: Phalombe', +'MW-21' => 'Malawi: Rumphi', +'MW-22' => 'Malawi: Salima', +'MW-05' => 'Malawi: Thyolo', +'MW-23' => 'Malawi: Zomba', + +'--MY' => '','-MY' => 'Malaysia', +'MY-01' => 'Malaysia: Johor', +'MY-02' => 'Malaysia: Kedah', +'MY-03' => 'Malaysia: Kelantan', +'MY-15' => 'Malaysia: Labuan', +'MY-04' => 'Malaysia: Melaka', +'MY-05' => 'Malaysia: Negeri Sembilan', +'MY-06' => 'Malaysia: Pahang', +'MY-07' => 'Malaysia: Perak', +'MY-08' => 'Malaysia: Perlis', +'MY-09' => 'Malaysia: Pulau Pinang', +'MY-16' => 'Malaysia: Sabah', +'MY-11' => 'Malaysia: Sarawak', +'MY-12' => 'Malaysia: Selangor', +'MY-13' => 'Malaysia: Terengganu', +'MY-14' => 'Malaysia: Wilayah Persekutuan', + +'--MV' => '','-MV' => 'Maldives', +'MV-02' => 'Maldives: Aliff', +'MV-20' => 'Maldives: Baa', +'MV-17' => 'Maldives: Daalu', +'MV-14' => 'Maldives: Faafu', +'MV-27' => 'Maldives: Gaafu Aliff', +'MV-28' => 'Maldives: Gaafu Daalu', +'MV-07' => 'Maldives: Haa Aliff', +'MV-23' => 'Maldives: Haa Daalu', +'MV-26' => 'Maldives: Kaafu', +'MV-05' => 'Maldives: Laamu', +'MV-03' => 'Maldives: Laviyani', +'MV-12' => 'Maldives: Meemu', +'MV-29' => 'Maldives: Naviyani', +'MV-25' => 'Maldives: Noonu', +'MV-13' => 'Maldives: Raa', +'MV-01' => 'Maldives: Seenu', +'MV-24' => 'Maldives: Shaviyani', +'MV-08' => 'Maldives: Thaa', +'MV-04' => 'Maldives: Waavu', + +'--ML' => '','-ML' => 'Mali', +'ML-01' => 'Mali: Bamako', +'ML-09' => 'Mali: Gao', +'ML-03' => 'Mali: Kayes', +'ML-10' => 'Mali: Kidal', +'ML-07' => 'Mali: Koulikoro', +'ML-04' => 'Mali: Mopti', +'ML-05' => 'Mali: Segou', +'ML-06' => 'Mali: Sikasso', +'ML-08' => 'Mali: Tombouctou', + +'--MR' => '','-MR' => 'Mauritania', +'MR-07' => 'Mauritania: Adrar', +'MR-03' => 'Mauritania: Assaba', +'MR-05' => 'Mauritania: Brakna', +'MR-08' => 'Mauritania: Dakhlet Nouadhibou', +'MR-04' => 'Mauritania: Gorgol', +'MR-10' => 'Mauritania: Guidimaka', +'MR-01' => 'Mauritania: Hodh Ech Chargui', +'MR-02' => 'Mauritania: Hodh El Gharbi', +'MR-12' => 'Mauritania: Inchiri', +'MR-09' => 'Mauritania: Tagant', +'MR-11' => 'Mauritania: Tiris Zemmour', +'MR-06' => 'Mauritania: Trarza', + +'--MU' => '','-MU' => 'Mauritius', +'MU-21' => 'Mauritius: Agalega Islands', +'MU-12' => 'Mauritius: Black River', +'MU-22' => 'Mauritius: Cargados Carajos', +'MU-13' => 'Mauritius: Flacq', +'MU-14' => 'Mauritius: Grand Port', +'MU-15' => 'Mauritius: Moka', +'MU-16' => 'Mauritius: Pamplemousses', +'MU-17' => 'Mauritius: Plaines Wilhems', +'MU-18' => 'Mauritius: Port Louis', +'MU-19' => 'Mauritius: Riviere du Rempart', +'MU-23' => 'Mauritius: Rodrigues', +'MU-20' => 'Mauritius: Savanne', + +'--MX' => '','-MX' => 'Mexico', +'MX-01' => 'Mexico: Aguascalientes', +'MX-03' => 'Mexico: Baja California Sur', +'MX-02' => 'Mexico: Baja California', +'MX-04' => 'Mexico: Campeche', +'MX-05' => 'Mexico: Chiapas', +'MX-06' => 'Mexico: Chihuahua', +'MX-07' => 'Mexico: Coahuila de Zaragoza', +'MX-08' => 'Mexico: Colima', +'MX-09' => 'Mexico: Distrito Federal', +'MX-10' => 'Mexico: Durango', +'MX-11' => 'Mexico: Guanajuato', +'MX-12' => 'Mexico: Guerrero', +'MX-13' => 'Mexico: Hidalgo', +'MX-14' => 'Mexico: Jalisco', +'MX-15' => 'Mexico: Mexico', +'MX-16' => 'Mexico: Michoacan de Ocampo', +'MX-17' => 'Mexico: Morelos', +'MX-18' => 'Mexico: Nayarit', +'MX-19' => 'Mexico: Nuevo Leon', +'MX-20' => 'Mexico: Oaxaca', +'MX-21' => 'Mexico: Puebla', +'MX-22' => 'Mexico: Queretaro de Arteaga', +'MX-23' => 'Mexico: Quintana Roo', +'MX-24' => 'Mexico: San Luis Potosi', +'MX-25' => 'Mexico: Sinaloa', +'MX-26' => 'Mexico: Sonora', +'MX-27' => 'Mexico: Tabasco', +'MX-28' => 'Mexico: Tamaulipas', +'MX-29' => 'Mexico: Tlaxcala', +'MX-30' => 'Mexico: Veracruz-Llave', +'MX-31' => 'Mexico: Yucatan', +'MX-32' => 'Mexico: Zacatecas', + +'--FM' => '','-FM' => 'Micronesia', +'FM-03' => 'Micronesia: Chuuk', +'FM-01' => 'Micronesia: Kosrae', +'FM-02' => 'Micronesia: Pohnpei', +'FM-04' => 'Micronesia: Yap', + +'--MD' => '','-MD' => 'Moldova', +'MD-46' => 'Moldova: Balti', +'MD-47' => 'Moldova: Cahul', +'MD-48' => 'Moldova: Chisinau', +'MD-50' => 'Moldova: Edinet', +'MD-51' => 'Moldova: Gagauzia', +'MD-52' => 'Moldova: Lapusna', +'MD-53' => 'Moldova: Orhei', +'MD-54' => 'Moldova: Soroca', +'MD-49' => 'Moldova: Stinga Nistrului', +'MD-55' => 'Moldova: Tighina', +'MD-56' => 'Moldova: Ungheni', + +'--MC' => '','-MC' => 'Monaco', +'MC-01' => 'Monaco: La Condamine', +'MC-02' => 'Monaco: Monaco', +'MC-03' => 'Monaco: Monte-Carlo', + +'--MN' => '','-MN' => 'Mongolia', +'MN-01' => 'Mongolia: Arhangay', +'MN-02' => 'Mongolia: Bayanhongor', +'MN-03' => 'Mongolia: Bayan-Olgiy', +'MN-21' => 'Mongolia: Bulgan', +'MN-23' => 'Mongolia: Darhan Uul', +'MN-05' => 'Mongolia: Darhan', +'MN-06' => 'Mongolia: Dornod', +'MN-07' => 'Mongolia: Dornogovi', +'MN-08' => 'Mongolia: Dundgovi', +'MN-09' => 'Mongolia: Dzavhan', +'MN-22' => 'Mongolia: Erdenet', +'MN-10' => 'Mongolia: Govi-Altay', +'MN-24' => 'Mongolia: Govi-Sumber', +'MN-11' => 'Mongolia: Hentiy', +'MN-12' => 'Mongolia: Hovd', +'MN-13' => 'Mongolia: Hovsgol', +'MN-14' => 'Mongolia: Omnogovi', +'MN-25' => 'Mongolia: Orhon', +'MN-15' => 'Mongolia: Ovorhangay', +'MN-16' => 'Mongolia: Selenge', +'MN-17' => 'Mongolia: Suhbaatar', +'MN-18' => 'Mongolia: Tov', +'MN-20' => 'Mongolia: Ulaanbaatar', +'MN-19' => 'Mongolia: Uvs', + +'--MS' => '','-MS' => 'Montserrat', +'MS-01' => 'Montserrat: Saint Anthony', +'MS-02' => 'Montserrat: Saint Georges', +'MS-03' => 'Montserrat: Saint Peter', + +'--MA' => '','-MA' => 'Morocco', +'MA-01' => 'Morocco: Agadir', +'MA-02' => 'Morocco: Al Hoceima', +'MA-03' => 'Morocco: Azilal', +'MA-04' => 'Morocco: Ben Slimane', +'MA-05' => 'Morocco: Beni Mellal', +'MA-06' => 'Morocco: Boulemane', +'MA-07' => 'Morocco: Casablanca', +'MA-08' => 'Morocco: Chaouen', +'MA-09' => 'Morocco: El Jadida', +'MA-10' => 'Morocco: El Kelaa des Srarhna', +'MA-11' => 'Morocco: Er Rachidia', +'MA-12' => 'Morocco: Essaouira', +'MA-13' => 'Morocco: Fes', +'MA-14' => 'Morocco: Figuig', +'MA-33' => 'Morocco: Guelmim', +'MA-34' => 'Morocco: Ifrane', +'MA-15' => 'Morocco: Kenitra', +'MA-16' => 'Morocco: Khemisset', +'MA-17' => 'Morocco: Khenifra', +'MA-18' => 'Morocco: Khouribga', +'MA-35' => 'Morocco: Laayoune', +'MA-41' => 'Morocco: Larache', +'MA-19' => 'Morocco: Marrakech', +'MA-20' => 'Morocco: Meknes', +'MA-21' => 'Morocco: Nador', +'MA-22' => 'Morocco: Ouarzazate', +'MA-23' => 'Morocco: Oujda', +'MA-24' => 'Morocco: Rabat-Sale', +'MA-25' => 'Morocco: Safi', +'MA-26' => 'Morocco: Settat', +'MA-38' => 'Morocco: Sidi Kacem', +'MA-27' => 'Morocco: Tanger', +'MA-36' => 'Morocco: Tan-Tan', +'MA-37' => 'Morocco: Taounate', +'MA-39' => 'Morocco: Taroudannt', +'MA-29' => 'Morocco: Tata', +'MA-30' => 'Morocco: Taza', +'MA-40' => 'Morocco: Tetouan', +'MA-32' => 'Morocco: Tiznit', + +'--MZ' => '','-MZ' => 'Mozambique', +'MZ-01' => 'Mozambique: Cabo Delgado', +'MZ-02' => 'Mozambique: Gaza', +'MZ-03' => 'Mozambique: Inhambane', +'MZ-10' => 'Mozambique: Manica', +'MZ-04' => 'Mozambique: Maputo', +'MZ-06' => 'Mozambique: Nampula', +'MZ-07' => 'Mozambique: Niassa', +'MZ-05' => 'Mozambique: Sofala', +'MZ-08' => 'Mozambique: Tete', +'MZ-09' => 'Mozambique: Zambezia', + +'--MM' => '','-MM' => 'Myanmar', +'MM-02' => 'Myanmar: Chin State', +'MM-03' => 'Myanmar: Irrawaddy', +'MM-04' => 'Myanmar: Kachin State', +'MM-05' => 'Myanmar: Karan State', +'MM-06' => 'Myanmar: Kayah State', +'MM-07' => 'Myanmar: Magwe', +'MM-08' => 'Myanmar: Mandalay', +'MM-13' => 'Myanmar: Mon State', +'MM-09' => 'Myanmar: Pegu', +'MM-01' => 'Myanmar: Rakhine State', +'MM-14' => 'Myanmar: Rangoon', +'MM-10' => 'Myanmar: Sagaing', +'MM-11' => 'Myanmar: Shan State', +'MM-12' => 'Myanmar: Tenasserim', +'MM-17' => 'Myanmar: Yangon', + +'--NA' => '','-NA' => 'Namibia', +'NA-01' => 'Namibia: Bethanien', +'NA-03' => 'Namibia: Boesmanland', +'NA-02' => 'Namibia: Caprivi Oos', +'NA-28' => 'Namibia: Caprivi', +'NA-22' => 'Namibia: Damaraland', +'NA-29' => 'Namibia: Erongo', +'NA-04' => 'Namibia: Gobabis', +'NA-05' => 'Namibia: Grootfontein', +'NA-30' => 'Namibia: Hardap', +'NA-23' => 'Namibia: Hereroland Oos', +'NA-24' => 'Namibia: Hereroland Wes', +'NA-06' => 'Namibia: Kaokoland', +'NA-31' => 'Namibia: Karas', +'NA-20' => 'Namibia: Karasburg', +'NA-07' => 'Namibia: Karibib', +'NA-25' => 'Namibia: Kavango', +'NA-08' => 'Namibia: Keetmanshoop', +'NA-32' => 'Namibia: Kunene', +'NA-09' => 'Namibia: Luderitz', +'NA-10' => 'Namibia: Maltahohe', +'NA-26' => 'Namibia: Mariental', +'NA-27' => 'Namibia: Namaland', +'NA-33' => 'Namibia: Ohangwena', +'NA-11' => 'Namibia: Okahandja', +'NA-34' => 'Namibia: Okavango', +'NA-35' => 'Namibia: Omaheke', +'NA-12' => 'Namibia: Omaruru', +'NA-36' => 'Namibia: Omusati', +'NA-37' => 'Namibia: Oshana', +'NA-38' => 'Namibia: Oshikoto', +'NA-13' => 'Namibia: Otjiwarongo', +'NA-39' => 'Namibia: Otjozondjupa', +'NA-14' => 'Namibia: Outjo', +'NA-15' => 'Namibia: Owambo', +'NA-16' => 'Namibia: Rehoboth', +'NA-17' => 'Namibia: Swakopmund', +'NA-18' => 'Namibia: Tsumeb', +'NA-21' => 'Namibia: Windhoek', + +'--NR' => '','-NR' => 'Nauru', +'NR-01' => 'Nauru: Aiwo', +'NR-02' => 'Nauru: Anabar', +'NR-03' => 'Nauru: Anetan', +'NR-04' => 'Nauru: Anibare', +'NR-05' => 'Nauru: Baiti', +'NR-06' => 'Nauru: Boe', +'NR-07' => 'Nauru: Buada', +'NR-08' => 'Nauru: Denigomodu', +'NR-09' => 'Nauru: Ewa', +'NR-10' => 'Nauru: Ijuw', +'NR-11' => 'Nauru: Meneng', +'NR-12' => 'Nauru: Nibok', +'NR-13' => 'Nauru: Uaboe', +'NR-14' => 'Nauru: Yaren', + +'--NP' => '','-NP' => 'Nepal', +'NP-01' => 'Nepal: Bagmati', +'NP-02' => 'Nepal: Bheri', +'NP-03' => 'Nepal: Dhawalagiri', +'NP-04' => 'Nepal: Gandaki', +'NP-05' => 'Nepal: Janakpur', +'NP-06' => 'Nepal: Karnali', +'NP-07' => 'Nepal: Kosi', +'NP-08' => 'Nepal: Lumbini', +'NP-09' => 'Nepal: Mahakali', +'NP-10' => 'Nepal: Mechi', +'NP-11' => 'Nepal: Narayani', +'NP-12' => 'Nepal: Rapti', +'NP-13' => 'Nepal: Sagarmatha', +'NP-14' => 'Nepal: Seti', + +'--NL' => '','-NL' => 'Netherlands', +'NL-01' => 'Netherlands: Drenthe', +'NL-16' => 'Netherlands: Flevoland', +'NL-02' => 'Netherlands: Friesland', +'NL-03' => 'Netherlands: Gelderland', +'NL-04' => 'Netherlands: Groningen', +'NL-05' => 'Netherlands: Limburg', +'NL-06' => 'Netherlands: Noord-Brabant', +'NL-07' => 'Netherlands: Noord-Holland', +'NL-15' => 'Netherlands: Overijssel', +'NL-09' => 'Netherlands: Utrecht', +'NL-10' => 'Netherlands: Zeeland', +'NL-11' => 'Netherlands: Zuid-Holland', + +'--NZ' => '','-NZ' => 'New Zealand', +'NZ-01' => 'New Zealand: Akaroa', +'NZ-03' => 'New Zealand: Amuri', +'NZ-04' => 'New Zealand: Ashburton', +'NZ-07' => 'New Zealand: Bay of Islands', +'NZ-08' => 'New Zealand: Bruce', +'NZ-09' => 'New Zealand: Buller', +'NZ-10' => 'New Zealand: Chatham Islands', +'NZ-11' => 'New Zealand: Cheviot', +'NZ-12' => 'New Zealand: Clifton', +'NZ-13' => 'New Zealand: Clutha', +'NZ-14' => 'New Zealand: Cook', +'NZ-16' => 'New Zealand: Dannevirke', +'NZ-17' => 'New Zealand: Egmont', +'NZ-18' => 'New Zealand: Eketahuna', +'NZ-19' => 'New Zealand: Ellesmere', +'NZ-20' => 'New Zealand: Eltham', +'NZ-21' => 'New Zealand: Eyre', +'NZ-22' => 'New Zealand: Featherston', +'NZ-24' => 'New Zealand: Franklin', +'NZ-26' => 'New Zealand: Golden Bay', +'NZ-27' => 'New Zealand: Great Barrier Island', +'NZ-28' => 'New Zealand: Grey', +'NZ-29' => 'New Zealand: Hauraki Plains', +'NZ-30' => 'New Zealand: Hawera', +'NZ-31' => 'New Zealand: Hawke\'s Bay', +'NZ-32' => 'New Zealand: Heathcote', +'NZ-D9' => 'New Zealand: Hikurangi', +'NZ-33' => 'New Zealand: Hobson', +'NZ-34' => 'New Zealand: Hokianga', +'NZ-35' => 'New Zealand: Horowhenua', +'NZ-D4' => 'New Zealand: Hurunui', +'NZ-36' => 'New Zealand: Hutt', +'NZ-37' => 'New Zealand: Inangahua', +'NZ-38' => 'New Zealand: Inglewood', +'NZ-39' => 'New Zealand: Kaikoura', +'NZ-40' => 'New Zealand: Kairanga', +'NZ-41' => 'New Zealand: Kiwitea', +'NZ-43' => 'New Zealand: Lake', +'NZ-45' => 'New Zealand: Mackenzie', +'NZ-46' => 'New Zealand: Malvern', +'NZ-E1' => 'New Zealand: Manaia', +'NZ-47' => 'New Zealand: Manawatu', +'NZ-48' => 'New Zealand: Mangonui', +'NZ-49' => 'New Zealand: Maniototo', +'NZ-50' => 'New Zealand: Marlborough', +'NZ-51' => 'New Zealand: Masterton', +'NZ-52' => 'New Zealand: Matamata', +'NZ-53' => 'New Zealand: Mount Herbert', +'NZ-54' => 'New Zealand: Ohinemuri', +'NZ-55' => 'New Zealand: Opotiki', +'NZ-56' => 'New Zealand: Oroua', +'NZ-57' => 'New Zealand: Otamatea', +'NZ-58' => 'New Zealand: Otorohanga', +'NZ-59' => 'New Zealand: Oxford', +'NZ-60' => 'New Zealand: Pahiatua', +'NZ-61' => 'New Zealand: Paparua', +'NZ-63' => 'New Zealand: Patea', +'NZ-65' => 'New Zealand: Piako', +'NZ-66' => 'New Zealand: Pohangina', +'NZ-67' => 'New Zealand: Raglan', +'NZ-68' => 'New Zealand: Rangiora', +'NZ-69' => 'New Zealand: Rangitikei', +'NZ-70' => 'New Zealand: Rodney', +'NZ-71' => 'New Zealand: Rotorua', +'NZ-E2' => 'New Zealand: Runanga', +'NZ-E3' => 'New Zealand: Saint Kilda', +'NZ-D5' => 'New Zealand: Silverpeaks', +'NZ-72' => 'New Zealand: Southland', +'NZ-73' => 'New Zealand: Stewart Island', +'NZ-74' => 'New Zealand: Stratford', +'NZ-D6' => 'New Zealand: Strathallan', +'NZ-76' => 'New Zealand: Taranaki', +'NZ-77' => 'New Zealand: Taumarunui', +'NZ-78' => 'New Zealand: Taupo', +'NZ-79' => 'New Zealand: Tauranga', +'NZ-E4' => 'New Zealand: Thames-Coromandel', +'NZ-81' => 'New Zealand: Tuapeka', +'NZ-82' => 'New Zealand: Vincent', +'NZ-83' => 'New Zealand: Waiapu', +'NZ-D8' => 'New Zealand: Waiheke', +'NZ-84' => 'New Zealand: Waihemo', +'NZ-85' => 'New Zealand: Waikato', +'NZ-86' => 'New Zealand: Waikohu', +'NZ-88' => 'New Zealand: Waimairi', +'NZ-89' => 'New Zealand: Waimarino', +'NZ-91' => 'New Zealand: Waimate West', +'NZ-90' => 'New Zealand: Waimate', +'NZ-92' => 'New Zealand: Waimea', +'NZ-93' => 'New Zealand: Waipa', +'NZ-95' => 'New Zealand: Waipawa', +'NZ-96' => 'New Zealand: Waipukurau', +'NZ-97' => 'New Zealand: Wairarapa South', +'NZ-98' => 'New Zealand: Wairewa', +'NZ-99' => 'New Zealand: Wairoa', +'NZ-A4' => 'New Zealand: Waitaki', +'NZ-A6' => 'New Zealand: Waitomo', +'NZ-A8' => 'New Zealand: Waitotara', +'NZ-E6' => 'New Zealand: Wallace', +'NZ-B2' => 'New Zealand: Wanganui', +'NZ-E5' => 'New Zealand: Waverley', +'NZ-B3' => 'New Zealand: Westland', +'NZ-B4' => 'New Zealand: Whakatane', +'NZ-A1' => 'New Zealand: Whangarei', +'NZ-A2' => 'New Zealand: Whangaroa', +'NZ-A3' => 'New Zealand: Woodmark', + +'--NI' => '','-NI' => 'Nicaragua', +'NI-01' => 'Nicaragua: Boaco', +'NI-02' => 'Nicaragua: Carazo', +'NI-03' => 'Nicaragua: Chinandega', +'NI-04' => 'Nicaragua: Chontales', +'NI-05' => 'Nicaragua: Esteli', +'NI-06' => 'Nicaragua: Granada', +'NI-07' => 'Nicaragua: Jinotega', +'NI-08' => 'Nicaragua: Leon', +'NI-09' => 'Nicaragua: Madriz', +'NI-10' => 'Nicaragua: Managua', +'NI-11' => 'Nicaragua: Masaya', +'NI-12' => 'Nicaragua: Matagalpa', +'NI-13' => 'Nicaragua: Nueva Segovia', +'NI-14' => 'Nicaragua: Rio San Juan', +'NI-15' => 'Nicaragua: Rivas', +'NI-16' => 'Nicaragua: Zelaya', + +'--NE' => '','-NE' => 'Niger', +'NE-01' => 'Niger: Agadez', +'NE-02' => 'Niger: Diffa', +'NE-03' => 'Niger: Dosso', +'NE-04' => 'Niger: Maradi', +'NE-05' => 'Niger: Niamey', +'NE-06' => 'Niger: Tahoua', +'NE-07' => 'Niger: Zinder', + +'--NG' => '','-NG' => 'Nigeria', +'NG-45' => 'Nigeria: Abia', +'NG-11' => 'Nigeria: Abuja Capital Territory', +'NG-35' => 'Nigeria: Adamawa', +'NG-21' => 'Nigeria: Akwa Ibom', +'NG-25' => 'Nigeria: Anambra', +'NG-46' => 'Nigeria: Bauchi', +'NG-52' => 'Nigeria: Bayelsa', +'NG-26' => 'Nigeria: Benue', +'NG-27' => 'Nigeria: Borno', +'NG-22' => 'Nigeria: Cross River', +'NG-36' => 'Nigeria: Delta', +'NG-53' => 'Nigeria: Ebonyi', +'NG-37' => 'Nigeria: Edo', +'NG-54' => 'Nigeria: Ekiti', +'NG-47' => 'Nigeria: Enugu', +'NG-55' => 'Nigeria: Gombe', +'NG-28' => 'Nigeria: Imo', +'NG-39' => 'Nigeria: Jigawa', +'NG-23' => 'Nigeria: Kaduna', +'NG-29' => 'Nigeria: Kano', +'NG-24' => 'Nigeria: Katsina', +'NG-40' => 'Nigeria: Kebbi', +'NG-41' => 'Nigeria: Kogi', +'NG-30' => 'Nigeria: Kwara', +'NG-05' => 'Nigeria: Lagos', +'NG-56' => 'Nigeria: Nassarawa', +'NG-31' => 'Nigeria: Niger', +'NG-16' => 'Nigeria: Ogun', +'NG-48' => 'Nigeria: Ondo', +'NG-42' => 'Nigeria: Osun', +'NG-32' => 'Nigeria: Oyo', +'NG-49' => 'Nigeria: Plateau', +'NG-50' => 'Nigeria: Rivers', +'NG-51' => 'Nigeria: Sokoto', +'NG-43' => 'Nigeria: Taraba', +'NG-44' => 'Nigeria: Yobe', +'NG-57' => 'Nigeria: Zamfara', + +'--KP' => '','-KP' => 'North Korea', +'KP-01' => 'North Korea: Chagang-do', +'KP-17' => 'North Korea: Hamgyong-bukto', +'KP-03' => 'North Korea: Hamgyong-namdo', +'KP-07' => 'North Korea: Hwanghae-bukto', +'KP-06' => 'North Korea: Hwanghae-namdo', +'KP-08' => 'North Korea: Kaesong-si', +'KP-09' => 'North Korea: Kangwon-do', +'KP-18' => 'North Korea: Najin Sonbong-si', +'KP-14' => 'North Korea: Namp\'o-si', +'KP-11' => 'North Korea: P\'yongan-bukto', +'KP-15' => 'North Korea: P\'yongan-namdo', +'KP-12' => 'North Korea: P\'yongyang-si', +'KP-13' => 'North Korea: Yanggang-do', + +'--NO' => '','-NO' => 'Norway', +'NO-01' => 'Norway: Akershus', +'NO-02' => 'Norway: Aust-Agder', +'NO-04' => 'Norway: Buskerud', +'NO-05' => 'Norway: Finnmark', +'NO-06' => 'Norway: Hedmark', +'NO-07' => 'Norway: Hordaland', +'NO-08' => 'Norway: More og Romsdal', +'NO-09' => 'Norway: Nordland', +'NO-10' => 'Norway: Nord-Trondelag', +'NO-11' => 'Norway: Oppland', +'NO-12' => 'Norway: Oslo', +'NO-13' => 'Norway: Ostfold', +'NO-14' => 'Norway: Rogaland', +'NO-15' => 'Norway: Sogn og Fjordane', +'NO-16' => 'Norway: Sor-Trondelag', +'NO-17' => 'Norway: Telemark', +'NO-18' => 'Norway: Troms', +'NO-19' => 'Norway: Vest-Agder', +'NO-20' => 'Norway: Vestfold', + +'--OM' => '','-OM' => 'Oman', +'OM-01' => 'Oman: Ad Dakhiliyah', +'OM-02' => 'Oman: Al Batinah', +'OM-03' => 'Oman: Al Wusta', +'OM-04' => 'Oman: Ash Sharqiyah', +'OM-05' => 'Oman: Az Zahirah', +'OM-06' => 'Oman: Masqat', +'OM-07' => 'Oman: Musandam', +'OM-08' => 'Oman: Zufar', + +'--PK' => '','-PK' => 'Pakistan', +'PK-06' => 'Pakistan: Azad Kashmir', +'PK-02' => 'Pakistan: Balochistan', +'PK-01' => 'Pakistan: Federally Administered Tribal Areas', +'PK-08' => 'Pakistan: Islamabad', +'PK-07' => 'Pakistan: Northern Areas', +'PK-03' => 'Pakistan: North-West Frontier', +'PK-04' => 'Pakistan: Punjab', +'PK-05' => 'Pakistan: Sindh', + +'--PA' => '','-PA' => 'Panama', +'PA-01' => 'Panama: Bocas del Toro', +'PA-02' => 'Panama: Chiriqui', +'PA-03' => 'Panama: Cocle', +'PA-04' => 'Panama: Colon', +'PA-05' => 'Panama: Darien', +'PA-06' => 'Panama: Herrera', +'PA-07' => 'Panama: Los Santos', +'PA-08' => 'Panama: Panama', +'PA-09' => 'Panama: San Blas', +'PA-10' => 'Panama: Veraguas', + +'--PG' => '','-PG' => 'Papua New Guinea', +'PG-01' => 'Papua New Guinea: Central', +'PG-08' => 'Papua New Guinea: Chimbu', +'PG-10' => 'Papua New Guinea: East New Britain', +'PG-11' => 'Papua New Guinea: East Sepik', +'PG-09' => 'Papua New Guinea: Eastern Highlands', +'PG-19' => 'Papua New Guinea: Enga', +'PG-02' => 'Papua New Guinea: Gulf', +'PG-12' => 'Papua New Guinea: Madang', +'PG-13' => 'Papua New Guinea: Manus', +'PG-03' => 'Papua New Guinea: Milne Bay', +'PG-14' => 'Papua New Guinea: Morobe', +'PG-20' => 'Papua New Guinea: National Capital', +'PG-15' => 'Papua New Guinea: New Ireland', +'PG-07' => 'Papua New Guinea: North Solomons', +'PG-04' => 'Papua New Guinea: Northern', +'PG-18' => 'Papua New Guinea: Sandaun', +'PG-05' => 'Papua New Guinea: Southern Highlands', +'PG-17' => 'Papua New Guinea: West New Britain', +'PG-16' => 'Papua New Guinea: Western Highlands', +'PG-06' => 'Papua New Guinea: Western', + +'--PY' => '','-PY' => 'Paraguay', +'PY-23' => 'Paraguay: Alto Paraguay', +'PY-01' => 'Paraguay: Alto Parana', +'PY-02' => 'Paraguay: Amambay', +'PY-03' => 'Paraguay: Boqueron', +'PY-04' => 'Paraguay: Caaguazu', +'PY-05' => 'Paraguay: Caazapa', +'PY-19' => 'Paraguay: Canindeyu', +'PY-06' => 'Paraguay: Central', +'PY-20' => 'Paraguay: Chaco', +'PY-07' => 'Paraguay: Concepcion', +'PY-08' => 'Paraguay: Cordillera', +'PY-10' => 'Paraguay: Guaira', +'PY-11' => 'Paraguay: Itapua', +'PY-12' => 'Paraguay: Misiones', +'PY-13' => 'Paraguay: Neembucu', +'PY-21' => 'Paraguay: Nueva Asuncion', +'PY-15' => 'Paraguay: Paraguari', +'PY-16' => 'Paraguay: Presidente Hayes', +'PY-17' => 'Paraguay: San Pedro', + +'--PE' => '','-PE' => 'Peru', +'PE-01' => 'Peru: Amazonas', +'PE-02' => 'Peru: Ancash', +'PE-03' => 'Peru: Apurimac', +'PE-04' => 'Peru: Arequipa', +'PE-05' => 'Peru: Ayacucho', +'PE-06' => 'Peru: Cajamarca', +'PE-07' => 'Peru: Callao', +'PE-08' => 'Peru: Cusco', +'PE-09' => 'Peru: Huancavelica', +'PE-10' => 'Peru: Huanuco', +'PE-11' => 'Peru: Ica', +'PE-12' => 'Peru: Junin', +'PE-13' => 'Peru: La Libertad', +'PE-14' => 'Peru: Lambayeque', +'PE-15' => 'Peru: Lima', +'PE-16' => 'Peru: Loreto', +'PE-17' => 'Peru: Madre de Dios', +'PE-18' => 'Peru: Moquegua', +'PE-19' => 'Peru: Pasco', +'PE-20' => 'Peru: Piura', +'PE-21' => 'Peru: Puno', +'PE-22' => 'Peru: San Martin', +'PE-23' => 'Peru: Tacna', +'PE-24' => 'Peru: Tumbes', +'PE-25' => 'Peru: Ucayali', + +'--PH' => '','-PH' => 'Philippines', +'PH-01' => 'Philippines: Abra', +'PH-02' => 'Philippines: Agusan del Norte', +'PH-03' => 'Philippines: Agusan del Sur', +'PH-04' => 'Philippines: Aklan', +'PH-05' => 'Philippines: Albay', +'PH-A1' => 'Philippines: Angeles', +'PH-06' => 'Philippines: Antique', +'PH-G8' => 'Philippines: Aurora', +'PH-A2' => 'Philippines: Bacolod', +'PH-A3' => 'Philippines: Bago', +'PH-A4' => 'Philippines: Baguio', +'PH-A5' => 'Philippines: Bais', +'PH-A6' => 'Philippines: Basilan City', +'PH-22' => 'Philippines: Basilan', +'PH-07' => 'Philippines: Bataan', +'PH-08' => 'Philippines: Batanes', +'PH-A7' => 'Philippines: Batangas City', +'PH-09' => 'Philippines: Batangas', +'PH-10' => 'Philippines: Benguet', +'PH-11' => 'Philippines: Bohol', +'PH-12' => 'Philippines: Bukidnon', +'PH-13' => 'Philippines: Bulacan', +'PH-A8' => 'Philippines: Butuan', +'PH-A9' => 'Philippines: Cabanatuan', +'PH-B1' => 'Philippines: Cadiz', +'PH-B2' => 'Philippines: Cagayan de Oro', +'PH-14' => 'Philippines: Cagayan', +'PH-B3' => 'Philippines: Calbayog', +'PH-B4' => 'Philippines: Caloocan', +'PH-15' => 'Philippines: Camarines Norte', +'PH-16' => 'Philippines: Camarines Sur', +'PH-17' => 'Philippines: Camiguin', +'PH-B5' => 'Philippines: Canlaon', +'PH-18' => 'Philippines: Capiz', +'PH-19' => 'Philippines: Catanduanes', +'PH-B6' => 'Philippines: Cavite City', +'PH-20' => 'Philippines: Cavite', +'PH-B7' => 'Philippines: Cebu City', +'PH-21' => 'Philippines: Cebu', +'PH-B8' => 'Philippines: Cotabato', +'PH-B9' => 'Philippines: Dagupan', +'PH-C1' => 'Philippines: Danao', +'PH-C2' => 'Philippines: Dapitan', +'PH-C3' => 'Philippines: Davao City', +'PH-25' => 'Philippines: Davao del Sur', +'PH-26' => 'Philippines: Davao Oriental', +'PH-24' => 'Philippines: Davao', +'PH-C4' => 'Philippines: Dipolog', +'PH-C5' => 'Philippines: Dumaguete', +'PH-23' => 'Philippines: Eastern Samar', +'PH-C6' => 'Philippines: General Santos', +'PH-C7' => 'Philippines: Gingoog', +'PH-27' => 'Philippines: Ifugao', +'PH-C8' => 'Philippines: Iligan', +'PH-28' => 'Philippines: Ilocos Norte', +'PH-29' => 'Philippines: Ilocos Sur', +'PH-C9' => 'Philippines: Iloilo City', +'PH-30' => 'Philippines: Iloilo', +'PH-D1' => 'Philippines: Iriga', +'PH-31' => 'Philippines: Isabela', +'PH-32' => 'Philippines: Kalinga-Apayao', +'PH-D2' => 'Philippines: La Carlota', +'PH-36' => 'Philippines: La Union', +'PH-33' => 'Philippines: Laguna', +'PH-34' => 'Philippines: Lanao del Norte', +'PH-35' => 'Philippines: Lanao del Sur', +'PH-D3' => 'Philippines: Laoag', +'PH-D4' => 'Philippines: Lapu-Lapu', +'PH-D5' => 'Philippines: Legaspi', +'PH-37' => 'Philippines: Leyte', +'PH-D6' => 'Philippines: Lipa', +'PH-D7' => 'Philippines: Lucena', +'PH-56' => 'Philippines: Maguindanao', +'PH-D8' => 'Philippines: Mandaue', +'PH-D9' => 'Philippines: Manila', +'PH-E1' => 'Philippines: Marawi', +'PH-38' => 'Philippines: Marinduque', +'PH-39' => 'Philippines: Masbate', +'PH-40' => 'Philippines: Mindoro Occidental', +'PH-41' => 'Philippines: Mindoro Oriental', +'PH-42' => 'Philippines: Misamis Occidental', +'PH-43' => 'Philippines: Misamis Oriental', +'PH-44' => 'Philippines: Mountain', +'PH-E2' => 'Philippines: Naga', +'PH-H3' => 'Philippines: Negros Occidental', +'PH-46' => 'Philippines: Negros Oriental', +'PH-57' => 'Philippines: North Cotabato', +'PH-67' => 'Philippines: Northern Samar', +'PH-47' => 'Philippines: Nueva Ecija', +'PH-48' => 'Philippines: Nueva Vizcaya', +'PH-E3' => 'Philippines: Olongapo', +'PH-E4' => 'Philippines: Ormoc', +'PH-E5' => 'Philippines: Oroquieta', +'PH-E6' => 'Philippines: Ozamis', +'PH-E7' => 'Philippines: Pagadian', +'PH-49' => 'Philippines: Palawan', +'PH-E8' => 'Philippines: Palayan', +'PH-50' => 'Philippines: Pampanga', +'PH-51' => 'Philippines: Pangasinan', +'PH-E9' => 'Philippines: Pasay', +'PH-F1' => 'Philippines: Puerto Princesa', +'PH-F2' => 'Philippines: Quezon City', +'PH-H2' => 'Philippines: Quezon', +'PH-68' => 'Philippines: Quirino', +'PH-53' => 'Philippines: Rizal', +'PH-54' => 'Philippines: Romblon', +'PH-F3' => 'Philippines: Roxas', +'PH-55' => 'Philippines: Samar', +'PH-F4' => 'Philippines: San Carlos', +'PH-F5' => 'Philippines: San Carlos', +'PH-F6' => 'Philippines: San Jose', +'PH-F7' => 'Philippines: San Pablo', +'PH-F8' => 'Philippines: Silay', +'PH-69' => 'Philippines: Siquijor', +'PH-58' => 'Philippines: Sorsogon', +'PH-70' => 'Philippines: South Cotabato', +'PH-59' => 'Philippines: Southern Leyte', +'PH-71' => 'Philippines: Sultan Kudarat', +'PH-60' => 'Philippines: Sulu', +'PH-61' => 'Philippines: Surigao del Norte', +'PH-62' => 'Philippines: Surigao del Sur', +'PH-F9' => 'Philippines: Surigao', +'PH-G1' => 'Philippines: Tacloban', +'PH-G2' => 'Philippines: Tagaytay', +'PH-G3' => 'Philippines: Tagbilaran', +'PH-G4' => 'Philippines: Tangub', +'PH-63' => 'Philippines: Tarlac', +'PH-72' => 'Philippines: Tawitawi', +'PH-G5' => 'Philippines: Toledo', +'PH-G6' => 'Philippines: Trece Martires', +'PH-64' => 'Philippines: Zambales', +'PH-65' => 'Philippines: Zamboanga del Norte', +'PH-66' => 'Philippines: Zamboanga del Sur', +'PH-G7' => 'Philippines: Zamboanga', + +'--PL' => '','-PL' => 'Poland', +'PL-23' => 'Poland: Biala Podlaska', +'PL-24' => 'Poland: Bialystok', +'PL-25' => 'Poland: Bielsko', +'PL-26' => 'Poland: Bydgoszcz', +'PL-27' => 'Poland: Chelm', +'PL-28' => 'Poland: Ciechanow', +'PL-29' => 'Poland: Czestochowa', +'PL-72' => 'Poland: Dolnoslaskie', +'PL-30' => 'Poland: Elblag', +'PL-31' => 'Poland: Gdansk', +'PL-32' => 'Poland: Gorzow', +'PL-33' => 'Poland: Jelenia Gora', +'PL-34' => 'Poland: Kalisz', +'PL-35' => 'Poland: Katowice', +'PL-36' => 'Poland: Kielce', +'PL-37' => 'Poland: Konin', +'PL-38' => 'Poland: Koszalin', +'PL-39' => 'Poland: Krakow', +'PL-40' => 'Poland: Krosno', +'PL-73' => 'Poland: Kujawsko-Pomorskie', +'PL-41' => 'Poland: Legnica', +'PL-42' => 'Poland: Leszno', +'PL-43' => 'Poland: Lodz', +'PL-74' => 'Poland: Lodzkie', +'PL-44' => 'Poland: Lomza', +'PL-75' => 'Poland: Lubelskie', +'PL-45' => 'Poland: Lublin', +'PL-76' => 'Poland: Lubuskie', +'PL-77' => 'Poland: Malopolskie', +'PL-78' => 'Poland: Mazowieckie', +'PL-46' => 'Poland: Nowy Sacz', +'PL-47' => 'Poland: Olsztyn', +'PL-48' => 'Poland: Opole', +'PL-79' => 'Poland: Opolskie', +'PL-49' => 'Poland: Ostroleka', +'PL-50' => 'Poland: Pila', +'PL-51' => 'Poland: Piotrkow', +'PL-52' => 'Poland: Plock', +'PL-80' => 'Poland: Podkarpackie', +'PL-81' => 'Poland: Podlaskie', +'PL-82' => 'Poland: Pomorskie', +'PL-53' => 'Poland: Poznan', +'PL-54' => 'Poland: Przemysl', +'PL-55' => 'Poland: Radom', +'PL-56' => 'Poland: Rzeszow', +'PL-57' => 'Poland: Siedlce', +'PL-58' => 'Poland: Sieradz', +'PL-59' => 'Poland: Skierniewice', +'PL-83' => 'Poland: Slaskie', +'PL-60' => 'Poland: Slupsk', +'PL-61' => 'Poland: Suwalki', +'PL-84' => 'Poland: Swietokrzyskie', +'PL-62' => 'Poland: Szczecin', +'PL-63' => 'Poland: Tarnobrzeg', +'PL-64' => 'Poland: Tarnow', +'PL-65' => 'Poland: Torun', +'PL-66' => 'Poland: Walbrzych', +'PL-85' => 'Poland: Warminsko-Mazurskie', +'PL-67' => 'Poland: Warszawa', +'PL-86' => 'Poland: Wielkopolskie', +'PL-68' => 'Poland: Wloclawek', +'PL-69' => 'Poland: Wroclaw', +'PL-87' => 'Poland: Zachodniopomorskie', +'PL-70' => 'Poland: Zamosc', +'PL-71' => 'Poland: Zielona Gora', + +'--PT' => '','-PT' => 'Portugal', +'PT-02' => 'Portugal: Aveiro', +'PT-23' => 'Portugal: Azores', +'PT-03' => 'Portugal: Beja', +'PT-04' => 'Portugal: Braga', +'PT-05' => 'Portugal: Braganca', +'PT-06' => 'Portugal: Castelo Branco', +'PT-07' => 'Portugal: Coimbra', +'PT-08' => 'Portugal: Evora', +'PT-09' => 'Portugal: Faro', +'PT-11' => 'Portugal: Guarda', +'PT-13' => 'Portugal: Leiria', +'PT-14' => 'Portugal: Lisboa', +'PT-10' => 'Portugal: Madeira', +'PT-16' => 'Portugal: Portalegre', +'PT-17' => 'Portugal: Porto', +'PT-18' => 'Portugal: Santarem', +'PT-19' => 'Portugal: Setubal', +'PT-20' => 'Portugal: Viana do Castelo', +'PT-21' => 'Portugal: Vila Real', +'PT-22' => 'Portugal: Viseu', + +'--QA' => '','-QA' => 'Qatar', +'QA-01' => 'Qatar: Ad Dawhah', +'QA-02' => 'Qatar: Al Ghuwariyah', +'QA-03' => 'Qatar: Al Jumaliyah', +'QA-04' => 'Qatar: Al Khawr', +'QA-10' => 'Qatar: Al Wakrah', +'QA-06' => 'Qatar: Ar Rayyan', +'QA-11' => 'Qatar: Jariyan al Batnah', +'QA-08' => 'Qatar: Madinat ach Shamal', +'QA-12' => 'Qatar: Umm Sa\'id', +'QA-09' => 'Qatar: Umm Salal', + +'--RO' => '','-RO' => 'Romania', +'RO-01' => 'Romania: Alba', +'RO-02' => 'Romania: Arad', +'RO-03' => 'Romania: Arges', +'RO-04' => 'Romania: Bacau', +'RO-05' => 'Romania: Bihor', +'RO-06' => 'Romania: Bistrita-Nasaud', +'RO-07' => 'Romania: Botosani', +'RO-08' => 'Romania: Braila', +'RO-09' => 'Romania: Brasov', +'RO-10' => 'Romania: Bucuresti', +'RO-11' => 'Romania: Buzau', +'RO-41' => 'Romania: Calarasi', +'RO-12' => 'Romania: Caras-Severin', +'RO-13' => 'Romania: Cluj', +'RO-14' => 'Romania: Constanta', +'RO-15' => 'Romania: Covasna', +'RO-16' => 'Romania: Dambovita', +'RO-17' => 'Romania: Dolj', +'RO-18' => 'Romania: Galati', +'RO-42' => 'Romania: Giurgiu', +'RO-19' => 'Romania: Gorj', +'RO-20' => 'Romania: Harghita', +'RO-21' => 'Romania: Hunedoara', +'RO-22' => 'Romania: Ialomita', +'RO-23' => 'Romania: Iasi', +'RO-43' => 'Romania: Ilfov', +'RO-25' => 'Romania: Maramures', +'RO-26' => 'Romania: Mehedinti', +'RO-27' => 'Romania: Mures', +'RO-28' => 'Romania: Neamt', +'RO-29' => 'Romania: Olt', +'RO-30' => 'Romania: Prahova', +'RO-31' => 'Romania: Salaj', +'RO-32' => 'Romania: Satu Mare', +'RO-33' => 'Romania: Sibiu', +'RO-34' => 'Romania: Suceava', +'RO-35' => 'Romania: Teleorman', +'RO-36' => 'Romania: Timis', +'RO-37' => 'Romania: Tulcea', +'RO-39' => 'Romania: Valcea', +'RO-38' => 'Romania: Vaslui', +'RO-40' => 'Romania: Vrancea', + +'--RU' => '','-RU' => 'Russian Federation', +'RU-01' => 'Russian Federation: Adygeya', +'RU-02' => 'Russian Federation: Aginsky Buryatsky AO', +'RU-04' => 'Russian Federation: Altaisky krai', +'RU-05' => 'Russian Federation: Amur', +'RU-06' => 'Russian Federation: Arkhangel\'sk', +'RU-07' => 'Russian Federation: Astrakhan\'', +'RU-08' => 'Russian Federation: Bashkortostan', +'RU-09' => 'Russian Federation: Belgorod', +'RU-10' => 'Russian Federation: Bryansk', +'RU-11' => 'Russian Federation: Buryat', +'RU-12' => 'Russian Federation: Chechnya', +'RU-13' => 'Russian Federation: Chelyabinsk', +'RU-14' => 'Russian Federation: Chita', +'RU-15' => 'Russian Federation: Chukot', +'RU-16' => 'Russian Federation: Chuvashia', +'RU-17' => 'Russian Federation: Dagestan', +'RU-18' => 'Russian Federation: Evenk', +'RU-03' => 'Russian Federation: Gorno-Altay', +'RU-19' => 'Russian Federation: Ingush', +'RU-20' => 'Russian Federation: Irkutsk', +'RU-21' => 'Russian Federation: Ivanovo', +'RU-22' => 'Russian Federation: Kabardin-Balkar', +'RU-23' => 'Russian Federation: Kaliningrad', +'RU-24' => 'Russian Federation: Kalmyk', +'RU-25' => 'Russian Federation: Kaluga', +'RU-26' => 'Russian Federation: Kamchatka', +'RU-27' => 'Russian Federation: Karachay-Cherkess', +'RU-28' => 'Russian Federation: Karelia', +'RU-29' => 'Russian Federation: Kemerovo', +'RU-30' => 'Russian Federation: Khabarovsk', +'RU-31' => 'Russian Federation: Khakass', +'RU-32' => 'Russian Federation: Khanty-Mansiy', +'RU-33' => 'Russian Federation: Kirov', +'RU-34' => 'Russian Federation: Komi', +'RU-35' => 'Russian Federation: Komi-Permyak', +'RU-36' => 'Russian Federation: Koryak', +'RU-37' => 'Russian Federation: Kostroma', +'RU-38' => 'Russian Federation: Krasnodar', +'RU-39' => 'Russian Federation: Krasnoyarsk', +'RU-40' => 'Russian Federation: Kurgan', +'RU-41' => 'Russian Federation: Kursk', +'RU-42' => 'Russian Federation: Leningrad', +'RU-43' => 'Russian Federation: Lipetsk', +'RU-44' => 'Russian Federation: Magadan', +'RU-45' => 'Russian Federation: Mariy-El', +'RU-46' => 'Russian Federation: Mordovia', +'RU-48' => 'Russian Federation: Moscow City', +'RU-47' => 'Russian Federation: Moskva', +'RU-49' => 'Russian Federation: Murmansk', +'RU-50' => 'Russian Federation: Nenets', +'RU-51' => 'Russian Federation: Nizhegorod', +'RU-68' => 'Russian Federation: North Ossetia', +'RU-52' => 'Russian Federation: Novgorod', +'RU-53' => 'Russian Federation: Novosibirsk', +'RU-54' => 'Russian Federation: Omsk', +'RU-56' => 'Russian Federation: Orel', +'RU-55' => 'Russian Federation: Orenburg', +'RU-57' => 'Russian Federation: Penza', +'RU-58' => 'Russian Federation: Perm\'', +'RU-59' => 'Russian Federation: Primor\'ye', +'RU-60' => 'Russian Federation: Pskov', +'RU-61' => 'Russian Federation: Rostov', +'RU-62' => 'Russian Federation: Ryazan\'', +'RU-66' => 'Russian Federation: Saint Petersburg City', +'RU-63' => 'Russian Federation: Sakha', +'RU-64' => 'Russian Federation: Sakhalin', +'RU-65' => 'Russian Federation: Samara', +'RU-67' => 'Russian Federation: Saratov', +'RU-69' => 'Russian Federation: Smolensk', +'RU-70' => 'Russian Federation: Stavropol\'', +'RU-71' => 'Russian Federation: Sverdlovsk', +'RU-72' => 'Russian Federation: Tambovskaya oblast', +'RU-73' => 'Russian Federation: Tatarstan', +'RU-74' => 'Russian Federation: Taymyr', +'RU-75' => 'Russian Federation: Tomsk', +'RU-76' => 'Russian Federation: Tula', +'RU-79' => 'Russian Federation: Tuva', +'RU-77' => 'Russian Federation: Tver\'', +'RU-78' => 'Russian Federation: Tyumen\'', +'RU-80' => 'Russian Federation: Udmurt', +'RU-81' => 'Russian Federation: Ul\'yanovsk', +'RU-82' => 'Russian Federation: Ust-Orda Buryat', +'RU-83' => 'Russian Federation: Vladimir', +'RU-84' => 'Russian Federation: Volgograd', +'RU-85' => 'Russian Federation: Vologda', +'RU-86' => 'Russian Federation: Voronezh', +'RU-87' => 'Russian Federation: Yamal-Nenets', +'RU-88' => 'Russian Federation: Yaroslavl\'', +'RU-89' => 'Russian Federation: Yevrey', + +'--RW' => '','-RW' => 'Rwanda', +'RW-01' => 'Rwanda: Butare', +'RW-02' => 'Rwanda: Byumba', +'RW-03' => 'Rwanda: Cyangugu', +'RW-04' => 'Rwanda: Gikongoro', +'RW-05' => 'Rwanda: Gisenyi', +'RW-06' => 'Rwanda: Gitarama', +'RW-07' => 'Rwanda: Kibungo', +'RW-08' => 'Rwanda: Kibuye', +'RW-09' => 'Rwanda: Kigali', +'RW-10' => 'Rwanda: Ruhengeri', + +'--SH' => '','-SH' => 'Saint Helena', +'SH-01' => 'Saint Helena: Ascension', +'SH-02' => 'Saint Helena: Saint Helena', +'SH-03' => 'Saint Helena: Tristan da Cunha', + +'--KN' => '','-KN' => 'Saint Kitts and Nevis', +'KN-01' => 'Saint Kitts and Nevis: Christ Church Nichola Town', +'KN-02' => 'Saint Kitts and Nevis: Saint Anne Sandy Point', +'KN-03' => 'Saint Kitts and Nevis: Saint George Basseterre', +'KN-04' => 'Saint Kitts and Nevis: Saint George Gingerland', +'KN-05' => 'Saint Kitts and Nevis: Saint James Windward', +'KN-06' => 'Saint Kitts and Nevis: Saint John Capisterre', +'KN-07' => 'Saint Kitts and Nevis: Saint John Figtree', +'KN-08' => 'Saint Kitts and Nevis: Saint Mary Cayon', +'KN-09' => 'Saint Kitts and Nevis: Saint Paul Capisterre', +'KN-10' => 'Saint Kitts and Nevis: Saint Paul Charlestown', +'KN-11' => 'Saint Kitts and Nevis: Saint Peter Basseterre', +'KN-12' => 'Saint Kitts and Nevis: Saint Thomas Lowland', +'KN-13' => 'Saint Kitts and Nevis: Saint Thomas Middle Island', +'KN-15' => 'Saint Kitts and Nevis: Trinity Palmetto Point', + +'--LC' => '','-LC' => 'Saint Lucia', +'LC-01' => 'Saint Lucia: Anse-la-Raye', +'LC-03' => 'Saint Lucia: Castries', +'LC-04' => 'Saint Lucia: Choiseul', +'LC-02' => 'Saint Lucia: Dauphin', +'LC-05' => 'Saint Lucia: Dennery', +'LC-06' => 'Saint Lucia: Gros-Islet', +'LC-07' => 'Saint Lucia: Laborie', +'LC-08' => 'Saint Lucia: Micoud', +'LC-11' => 'Saint Lucia: Praslin', +'LC-09' => 'Saint Lucia: Soufriere', +'LC-10' => 'Saint Lucia: Vieux-Fort', + +'--VC' => '','-VC' => 'Saint Vincent and the Grenadines', +'VC-01' => 'Saint Vincent and the Grenadines: Charlotte', +'VC-06' => 'Saint Vincent and the Grenadines: Grenadines', +'VC-02' => 'Saint Vincent and the Grenadines: Saint Andrew', +'VC-03' => 'Saint Vincent and the Grenadines: Saint David', +'VC-04' => 'Saint Vincent and the Grenadines: Saint George', +'VC-05' => 'Saint Vincent and the Grenadines: Saint Patrick', + +'--WS' => '','-WS' => 'Samoa', +'WS-02' => 'Samoa: Aiga-i-le-Tai', +'WS-03' => 'Samoa: Atua', +'WS-04' => 'Samoa: Fa', +'WS-05' => 'Samoa: Gaga', +'WS-07' => 'Samoa: Gagaifomauga', +'WS-08' => 'Samoa: Palauli', +'WS-09' => 'Samoa: Satupa', +'WS-10' => 'Samoa: Tuamasaga', +'WS-06' => 'Samoa: Va', +'WS-11' => 'Samoa: Vaisigano', + +'--SM' => '','-SM' => 'San Marino', +'SM-01' => 'San Marino: Acquaviva', +'SM-06' => 'San Marino: Borgo Maggiore', +'SM-02' => 'San Marino: Chiesanuova', +'SM-03' => 'San Marino: Domagnano', +'SM-04' => 'San Marino: Faetano', +'SM-05' => 'San Marino: Fiorentino', +'SM-08' => 'San Marino: Monte Giardino', +'SM-07' => 'San Marino: San Marino', +'SM-09' => 'San Marino: Serravalle', + +'--ST' => '','-ST' => 'Sao Tome and Principe', +'ST-01' => 'Sao Tome and Principe: Principe', +'ST-02' => 'Sao Tome and Principe: Sao Tome', + +'--SA' => '','-SA' => 'Saudi Arabia', +'SA-02' => 'Saudi Arabia: Al Bahah', +'SA-15' => 'Saudi Arabia: Al Hudud ash Shamaliyah', +'SA-03' => 'Saudi Arabia: Al Jawf', +'SA-20' => 'Saudi Arabia: Al Jawf', +'SA-05' => 'Saudi Arabia: Al Madinah', +'SA-08' => 'Saudi Arabia: Al Qasim', +'SA-09' => 'Saudi Arabia: Al Qurayyat', +'SA-10' => 'Saudi Arabia: Ar Riyad', +'SA-06' => 'Saudi Arabia: Ash Sharqiyah', +'SA-13' => 'Saudi Arabia: Ha\'il', +'SA-17' => 'Saudi Arabia: Jizan', +'SA-14' => 'Saudi Arabia: Makkah', +'SA-16' => 'Saudi Arabia: Najran', +'SA-19' => 'Saudi Arabia: Tabuk', + +'--SN' => '','-SN' => 'Senegal', +'SN-01' => 'Senegal: Dakar', +'SN-03' => 'Senegal: Diourbel', +'SN-09' => 'Senegal: Fatick', +'SN-10' => 'Senegal: Kaolack', +'SN-11' => 'Senegal: Kolda', +'SN-08' => 'Senegal: Louga', +'SN-04' => 'Senegal: Saint-Louis', +'SN-05' => 'Senegal: Tambacounda', +'SN-07' => 'Senegal: Thies', +'SN-12' => 'Senegal: Ziguinchor', + +'--RS' => '','-RS' => 'Serbia', +'RS-01' => 'Serbia: Kosovo', +'RS-02' => 'Serbia: Vojvodina', + +'--SC' => '','-SC' => 'Seychelles', +'SC-01' => 'Seychelles: Anse aux Pins', +'SC-02' => 'Seychelles: Anse Boileau', +'SC-03' => 'Seychelles: Anse Etoile', +'SC-04' => 'Seychelles: Anse Louis', +'SC-05' => 'Seychelles: Anse Royale', +'SC-06' => 'Seychelles: Baie Lazare', +'SC-07' => 'Seychelles: Baie Sainte Anne', +'SC-08' => 'Seychelles: Beau Vallon', +'SC-09' => 'Seychelles: Bel Air', +'SC-10' => 'Seychelles: Bel Ombre', +'SC-11' => 'Seychelles: Cascade', +'SC-12' => 'Seychelles: Glacis', +'SC-13' => 'Seychelles: Grand\' Anse', +'SC-14' => 'Seychelles: Grand\' Anse', +'SC-15' => 'Seychelles: La Digue', +'SC-16' => 'Seychelles: La Riviere Anglaise', +'SC-17' => 'Seychelles: Mont Buxton', +'SC-18' => 'Seychelles: Mont Fleuri', +'SC-19' => 'Seychelles: Plaisance', +'SC-20' => 'Seychelles: Pointe La Rue', +'SC-21' => 'Seychelles: Port Glaud', +'SC-22' => 'Seychelles: Saint Louis', +'SC-23' => 'Seychelles: Takamaka', + +'--SL' => '','-SL' => 'Sierra Leone', +'SL-01' => 'Sierra Leone: Eastern', +'SL-02' => 'Sierra Leone: Northern', +'SL-03' => 'Sierra Leone: Southern', +'SL-04' => 'Sierra Leone: Western Area', + +'--SK' => '','-SK' => 'Slovakia', +'SK-01' => 'Slovakia: Banska Bystrica', +'SK-02' => 'Slovakia: Bratislava', +'SK-03' => 'Slovakia: Kosice', +'SK-04' => 'Slovakia: Nitra', +'SK-05' => 'Slovakia: Presov', +'SK-06' => 'Slovakia: Trencin', +'SK-07' => 'Slovakia: Trnava', +'SK-08' => 'Slovakia: Zilina', + +'--SI' => '','-SI' => 'Slovenia', +'SI-01' => 'Slovenia: Ajdovscina', +'SI-02' => 'Slovenia: Beltinci', +'SI-03' => 'Slovenia: Bled', +'SI-04' => 'Slovenia: Bohinj', +'SI-05' => 'Slovenia: Borovnica', +'SI-06' => 'Slovenia: Bovec', +'SI-07' => 'Slovenia: Brda', +'SI-08' => 'Slovenia: Brezice', +'SI-09' => 'Slovenia: Brezovica', +'SI-11' => 'Slovenia: Celje', +'SI-12' => 'Slovenia: Cerklje na Gorenjskem', +'SI-13' => 'Slovenia: Cerknica', +'SI-14' => 'Slovenia: Cerkno', +'SI-15' => 'Slovenia: Crensovci', +'SI-16' => 'Slovenia: Crna na Koroskem', +'SI-17' => 'Slovenia: Crnomelj', +'SI-19' => 'Slovenia: Divaca', +'SI-20' => 'Slovenia: Dobrepolje', +'SI-G4' => 'Slovenia: Dobrova-Horjul-Polhov Gradec', +'SI-22' => 'Slovenia: Dol pri Ljubljani', +'SI-G7' => 'Slovenia: Domzale', +'SI-24' => 'Slovenia: Dornava', +'SI-25' => 'Slovenia: Dravograd', +'SI-26' => 'Slovenia: Duplek', +'SI-27' => 'Slovenia: Gorenja Vas-Poljane', +'SI-28' => 'Slovenia: Gorisnica', +'SI-29' => 'Slovenia: Gornja Radgona', +'SI-30' => 'Slovenia: Gornji Grad', +'SI-31' => 'Slovenia: Gornji Petrovci', +'SI-32' => 'Slovenia: Grosuplje', +'SI-34' => 'Slovenia: Hrastnik', +'SI-35' => 'Slovenia: Hrpelje-Kozina', +'SI-36' => 'Slovenia: Idrija', +'SI-37' => 'Slovenia: Ig', +'SI-38' => 'Slovenia: Ilirska Bistrica', +'SI-39' => 'Slovenia: Ivancna Gorica', +'SI-40' => 'Slovenia: Izola-Isola', +'SI-H4' => 'Slovenia: Jesenice', +'SI-42' => 'Slovenia: Jursinci', +'SI-H6' => 'Slovenia: Kamnik', +'SI-44' => 'Slovenia: Kanal', +'SI-45' => 'Slovenia: Kidricevo', +'SI-46' => 'Slovenia: Kobarid', +'SI-47' => 'Slovenia: Kobilje', +'SI-H7' => 'Slovenia: Kocevje', +'SI-49' => 'Slovenia: Komen', +'SI-50' => 'Slovenia: Koper-Capodistria', +'SI-51' => 'Slovenia: Kozje', +'SI-52' => 'Slovenia: Kranj', +'SI-53' => 'Slovenia: Kranjska Gora', +'SI-54' => 'Slovenia: Krsko', +'SI-55' => 'Slovenia: Kungota', +'SI-I2' => 'Slovenia: Kuzma', +'SI-57' => 'Slovenia: Lasko', +'SI-I3' => 'Slovenia: Lenart', +'SI-I5' => 'Slovenia: Litija', +'SI-61' => 'Slovenia: Ljubljana', +'SI-62' => 'Slovenia: Ljubno', +'SI-I6' => 'Slovenia: Ljutomer', +'SI-64' => 'Slovenia: Logatec', +'SI-I7' => 'Slovenia: Loska Dolina', +'SI-66' => 'Slovenia: Loski Potok', +'SI-I9' => 'Slovenia: Luce', +'SI-68' => 'Slovenia: Lukovica', +'SI-J1' => 'Slovenia: Majsperk', +'SI-J2' => 'Slovenia: Maribor', +'SI-71' => 'Slovenia: Medvode', +'SI-72' => 'Slovenia: Menges', +'SI-73' => 'Slovenia: Metlika', +'SI-74' => 'Slovenia: Mezica', +'SI-J5' => 'Slovenia: Miren-Kostanjevica', +'SI-76' => 'Slovenia: Mislinja', +'SI-77' => 'Slovenia: Moravce', +'SI-78' => 'Slovenia: Moravske Toplice', +'SI-79' => 'Slovenia: Mozirje', +'SI-80' => 'Slovenia: Murska Sobota', +'SI-81' => 'Slovenia: Muta', +'SI-82' => 'Slovenia: Naklo', +'SI-83' => 'Slovenia: Nazarje', +'SI-84' => 'Slovenia: Nova Gorica', +'SI-J7' => 'Slovenia: Novo Mesto', +'SI-86' => 'Slovenia: Odranci', +'SI-87' => 'Slovenia: Ormoz', +'SI-88' => 'Slovenia: Osilnica', +'SI-89' => 'Slovenia: Pesnica', +'SI-J9' => 'Slovenia: Piran', +'SI-91' => 'Slovenia: Pivka', +'SI-92' => 'Slovenia: Podcetrtek', +'SI-94' => 'Slovenia: Postojna', +'SI-K5' => 'Slovenia: Preddvor', +'SI-K7' => 'Slovenia: Ptuj', +'SI-97' => 'Slovenia: Puconci', +'SI-98' => 'Slovenia: Racam', +'SI-99' => 'Slovenia: Radece', +'SI-A1' => 'Slovenia: Radenci', +'SI-A2' => 'Slovenia: Radlje ob Dravi', +'SI-A3' => 'Slovenia: Radovljica', +'SI-L1' => 'Slovenia: Ribnica', +'SI-A7' => 'Slovenia: Rogaska Slatina', +'SI-A6' => 'Slovenia: Rogasovci', +'SI-A8' => 'Slovenia: Rogatec', +'SI-L3' => 'Slovenia: Ruse', +'SI-B1' => 'Slovenia: Semic', +'SI-B2' => 'Slovenia: Sencur', +'SI-B3' => 'Slovenia: Sentilj', +'SI-B4' => 'Slovenia: Sentjernej', +'SI-L7' => 'Slovenia: Sentjur pri Celju', +'SI-B6' => 'Slovenia: Sevnica', +'SI-B7' => 'Slovenia: Sezana', +'SI-B8' => 'Slovenia: Skocjan', +'SI-B9' => 'Slovenia: Skofja Loka', +'SI-C1' => 'Slovenia: Skofljica', +'SI-C2' => 'Slovenia: Slovenj Gradec', +'SI-L8' => 'Slovenia: Slovenska Bistrica', +'SI-C4' => 'Slovenia: Slovenske Konjice', +'SI-C5' => 'Slovenia: Smarje pri Jelsah', +'SI-C6' => 'Slovenia: Smartno ob Paki', +'SI-C7' => 'Slovenia: Sostanj', +'SI-C8' => 'Slovenia: Starse', +'SI-C9' => 'Slovenia: Store', +'SI-D1' => 'Slovenia: Sveti Jurij', +'SI-D2' => 'Slovenia: Tolmin', +'SI-D3' => 'Slovenia: Trbovlje', +'SI-D4' => 'Slovenia: Trebnje', +'SI-D5' => 'Slovenia: Trzic', +'SI-D6' => 'Slovenia: Turnisce', +'SI-D7' => 'Slovenia: Velenje', +'SI-D8' => 'Slovenia: Velike Lasce', +'SI-N2' => 'Slovenia: Videm', +'SI-E1' => 'Slovenia: Vipava', +'SI-E2' => 'Slovenia: Vitanje', +'SI-E3' => 'Slovenia: Vodice', +'SI-N3' => 'Slovenia: Vojnik', +'SI-E5' => 'Slovenia: Vrhnika', +'SI-E6' => 'Slovenia: Vuzenica', +'SI-E7' => 'Slovenia: Zagorje ob Savi', +'SI-N5' => 'Slovenia: Zalec', +'SI-E9' => 'Slovenia: Zavrc', +'SI-F1' => 'Slovenia: Zelezniki', +'SI-F2' => 'Slovenia: Ziri', +'SI-F3' => 'Slovenia: Zrece', + +'--SB' => '','-SB' => 'Solomon Islands', +'SB-05' => 'Solomon Islands: Central', +'SB-06' => 'Solomon Islands: Guadalcanal', +'SB-07' => 'Solomon Islands: Isabel', +'SB-08' => 'Solomon Islands: Makira', +'SB-03' => 'Solomon Islands: Malaita', +'SB-09' => 'Solomon Islands: Temotu', +'SB-04' => 'Solomon Islands: Western', + +'--SO' => '','-SO' => 'Somalia', +'SO-01' => 'Somalia: Bakool', +'SO-02' => 'Somalia: Banaadir', +'SO-03' => 'Somalia: Bari', +'SO-04' => 'Somalia: Bay', +'SO-05' => 'Somalia: Galguduud', +'SO-06' => 'Somalia: Gedo', +'SO-07' => 'Somalia: Hiiraan', +'SO-08' => 'Somalia: Jubbada Dhexe', +'SO-09' => 'Somalia: Jubbada Hoose', +'SO-10' => 'Somalia: Mudug', +'SO-11' => 'Somalia: Nugaal', +'SO-12' => 'Somalia: Sanaag', +'SO-13' => 'Somalia: Shabeellaha Dhexe', +'SO-14' => 'Somalia: Shabeellaha Hoose', +'SO-15' => 'Somalia: Togdheer', +'SO-16' => 'Somalia: Woqooyi Galbeed', + +'--ZA' => '','-ZA' => 'South Africa', +'ZA-05' => 'South Africa: Eastern Cape', +'ZA-03' => 'South Africa: Free State', +'ZA-06' => 'South Africa: Gauteng', +'ZA-02' => 'South Africa: KwaZulu-Natal', +'ZA-09' => 'South Africa: Limpopo', +'ZA-07' => 'South Africa: Mpumalanga', +'ZA-08' => 'South Africa: Northern Cape', +'ZA-10' => 'South Africa: North-West', +'ZA-11' => 'South Africa: Western Cape', + +'--KR' => '','-KR' => 'South Korea', +'KR-01' => 'South Korea: Cheju-do', +'KR-03' => 'South Korea: Cholla-bukto', +'KR-16' => 'South Korea: Cholla-namdo', +'KR-05' => 'South Korea: Ch\'ungch\'ong-bukto', +'KR-17' => 'South Korea: Ch\'ungch\'ong-namdo', +'KR-12' => 'South Korea: Inch\'on-jikhalsi', +'KR-06' => 'South Korea: Kangwon-do', +'KR-18' => 'South Korea: Kwangju-jikhalsi', +'KR-13' => 'South Korea: Kyonggi-do', +'KR-14' => 'South Korea: Kyongsang-bukto', +'KR-20' => 'South Korea: Kyongsang-namdo', +'KR-10' => 'South Korea: Pusan-jikhalsi', +'KR-11' => 'South Korea: Seoul-t\'ukpyolsi', +'KR-15' => 'South Korea: Taegu-jikhalsi', +'KR-19' => 'South Korea: Taejon-jikhalsi', +'KR-21' => 'South Korea: Ulsan-gwangyoksi', + +'--ES' => '','-ES' => 'Spain', +'ES-51' => 'Spain: Andalucia', +'ES-52' => 'Spain: Aragon', +'ES-34' => 'Spain: Asturias', +'ES-53' => 'Spain: Canarias', +'ES-39' => 'Spain: Cantabria', +'ES-55' => 'Spain: Castilla y Leon', +'ES-54' => 'Spain: Castilla-La Mancha', +'ES-56' => 'Spain: Catalonia', +'ES-60' => 'Spain: Comunidad Valenciana', +'ES-57' => 'Spain: Extremadura', +'ES-58' => 'Spain: Galicia', +'ES-07' => 'Spain: Islas Baleares', +'ES-27' => 'Spain: La Rioja', +'ES-29' => 'Spain: Madrid', +'ES-31' => 'Spain: Murcia', +'ES-32' => 'Spain: Navarra', +'ES-59' => 'Spain: Pais Vasco', + +'--LK' => '','-LK' => 'Sri Lanka', +'LK-01' => 'Sri Lanka: Amparai', +'LK-02' => 'Sri Lanka: Anuradhapura', +'LK-03' => 'Sri Lanka: Badulla', +'LK-04' => 'Sri Lanka: Batticaloa', +'LK-23' => 'Sri Lanka: Colombo', +'LK-06' => 'Sri Lanka: Galle', +'LK-24' => 'Sri Lanka: Gampaha', +'LK-07' => 'Sri Lanka: Hambantota', +'LK-25' => 'Sri Lanka: Jaffna', +'LK-09' => 'Sri Lanka: Kalutara', +'LK-10' => 'Sri Lanka: Kandy', +'LK-11' => 'Sri Lanka: Kegalla', +'LK-12' => 'Sri Lanka: Kurunegala', +'LK-26' => 'Sri Lanka: Mannar', +'LK-14' => 'Sri Lanka: Matale', +'LK-15' => 'Sri Lanka: Matara', +'LK-16' => 'Sri Lanka: Moneragala', +'LK-27' => 'Sri Lanka: Mullaittivu', +'LK-17' => 'Sri Lanka: Nuwara Eliya', +'LK-18' => 'Sri Lanka: Polonnaruwa', +'LK-19' => 'Sri Lanka: Puttalam', +'LK-20' => 'Sri Lanka: Ratnapura', +'LK-21' => 'Sri Lanka: Trincomalee', +'LK-28' => 'Sri Lanka: Vavuniya', + +'--SD' => '','-SD' => 'Sudan', +'SD-28' => 'Sudan: Al Istiwa\'iyah', +'SD-29' => 'Sudan: Al Khartum', +'SD-27' => 'Sudan: Al Wusta', +'SD-30' => 'Sudan: Ash Shamaliyah', +'SD-31' => 'Sudan: Ash Sharqiyah', +'SD-32' => 'Sudan: Bahr al Ghazal', +'SD-33' => 'Sudan: Darfur', +'SD-34' => 'Sudan: Kurdufan', + +'--SR' => '','-SR' => 'Suriname', +'SR-10' => 'Suriname: Brokopondo', +'SR-11' => 'Suriname: Commewijne', +'SR-12' => 'Suriname: Coronie', +'SR-13' => 'Suriname: Marowijne', +'SR-14' => 'Suriname: Nickerie', +'SR-15' => 'Suriname: Para', +'SR-16' => 'Suriname: Paramaribo', +'SR-17' => 'Suriname: Saramacca', +'SR-18' => 'Suriname: Sipaliwini', +'SR-19' => 'Suriname: Wanica', + +'--SZ' => '','-SZ' => 'Swaziland', +'SZ-01' => 'Swaziland: Hhohho', +'SZ-02' => 'Swaziland: Lubombo', +'SZ-03' => 'Swaziland: Manzini', +'SZ-05' => 'Swaziland: Praslin', +'SZ-04' => 'Swaziland: Shiselweni', + +'--SE' => '','-SE' => 'Sweden', +'SE-01' => 'Sweden: Alvsborgs Lan', +'SE-02' => 'Sweden: Blekinge Lan', +'SE-10' => 'Sweden: Dalarnas Lan', +'SE-03' => 'Sweden: Gavleborgs Lan', +'SE-04' => 'Sweden: Goteborgs och Bohus Lan', +'SE-05' => 'Sweden: Gotlands Lan', +'SE-06' => 'Sweden: Hallands Lan', +'SE-07' => 'Sweden: Jamtlands Lan', +'SE-08' => 'Sweden: Jonkopings Lan', +'SE-09' => 'Sweden: Kalmar Lan', +'SE-11' => 'Sweden: Kristianstads Lan', +'SE-12' => 'Sweden: Kronobergs Lan', +'SE-13' => 'Sweden: Malmohus Lan', +'SE-14' => 'Sweden: Norrbottens Lan', +'SE-15' => 'Sweden: Orebro Lan', +'SE-16' => 'Sweden: Ostergotlands Lan', +'SE-27' => 'Sweden: Skane Lan', +'SE-17' => 'Sweden: Skaraborgs Lan', +'SE-18' => 'Sweden: Sodermanlands Lan', +'SE-26' => 'Sweden: Stockholms Lan', +'SE-21' => 'Sweden: Uppsala Lan', +'SE-22' => 'Sweden: Varmlands Lan', +'SE-23' => 'Sweden: Vasterbottens Lan', +'SE-24' => 'Sweden: Vasternorrlands Lan', +'SE-25' => 'Sweden: Vastmanlands Lan', +'SE-28' => 'Sweden: Vastra Gotaland', + +'--CH' => '','-CH' => 'Switzerland', +'CH-01' => 'Switzerland: Aargau', +'CH-02' => 'Switzerland: Ausser-Rhoden', +'CH-03' => 'Switzerland: Basel-Landschaft', +'CH-04' => 'Switzerland: Basel-Stadt', +'CH-05' => 'Switzerland: Bern', +'CH-06' => 'Switzerland: Fribourg', +'CH-07' => 'Switzerland: Geneve', +'CH-08' => 'Switzerland: Glarus', +'CH-09' => 'Switzerland: Graubunden', +'CH-10' => 'Switzerland: Inner-Rhoden', +'CH-26' => 'Switzerland: Jura', +'CH-11' => 'Switzerland: Luzern', +'CH-12' => 'Switzerland: Neuchatel', +'CH-13' => 'Switzerland: Nidwalden', +'CH-14' => 'Switzerland: Obwalden', +'CH-15' => 'Switzerland: Sankt Gallen', +'CH-16' => 'Switzerland: Schaffhausen', +'CH-17' => 'Switzerland: Schwyz', +'CH-18' => 'Switzerland: Solothurn', +'CH-19' => 'Switzerland: Thurgau', +'CH-20' => 'Switzerland: Ticino', +'CH-21' => 'Switzerland: Uri', +'CH-22' => 'Switzerland: Valais', +'CH-23' => 'Switzerland: Vaud', +'CH-24' => 'Switzerland: Zug', +'CH-25' => 'Switzerland: Zurich', + +'--SY' => '','-SY' => 'Syrian Arab Republic', +'SY-01' => 'Syrian Arab Republic: Al Hasakah', +'SY-02' => 'Syrian Arab Republic: Al Ladhiqiyah', +'SY-03' => 'Syrian Arab Republic: Al Qunaytirah', +'SY-04' => 'Syrian Arab Republic: Ar Raqqah', +'SY-05' => 'Syrian Arab Republic: As Suwayda\'', +'SY-06' => 'Syrian Arab Republic: Dar', +'SY-07' => 'Syrian Arab Republic: Dayr az Zawr', +'SY-13' => 'Syrian Arab Republic: Dimashq', +'SY-09' => 'Syrian Arab Republic: Halab', +'SY-10' => 'Syrian Arab Republic: Hamah', +'SY-11' => 'Syrian Arab Republic: Hims', +'SY-12' => 'Syrian Arab Republic: Idlib', +'SY-08' => 'Syrian Arab Republic: Rif Dimashq', +'SY-14' => 'Syrian Arab Republic: Tartus', + +'--TW' => '','-TW' => 'Taiwan', +'TW-01' => 'Taiwan: Fu-chien', +'TW-02' => 'Taiwan: Kao-hsiung', +'TW-03' => 'Taiwan: T\'ai-pei', +'TW-04' => 'Taiwan: T\'ai-wan', + +'--TJ' => '','-TJ' => 'Tajikistan', +'TJ-02' => 'Tajikistan: Khatlon', +'TJ-01' => 'Tajikistan: Kuhistoni Badakhshon', +'TJ-03' => 'Tajikistan: Sughd', + +'--TZ' => '','-TZ' => 'Tanwzania', +'TZ-01' => 'Tanwzania: Arusha', +'TZ-23' => 'Tanwzania: Dar es Salaam', +'TZ-03' => 'Tanwzania: Dodoma', +'TZ-04' => 'Tanwzania: Iringa', +'TZ-19' => 'Tanwzania: Kagera', +'TZ-05' => 'Tanwzania: Kigoma', +'TZ-06' => 'Tanwzania: Kilimanjaro', +'TZ-07' => 'Tanwzania: Lindi', +'TZ-08' => 'Tanwzania: Mara', +'TZ-09' => 'Tanwzania: Mbeya', +'TZ-10' => 'Tanwzania: Morogoro', +'TZ-11' => 'Tanwzania: Mtwara', +'TZ-12' => 'Tanwzania: Mwanza', +'TZ-13' => 'Tanwzania: Pemba North', +'TZ-20' => 'Tanwzania: Pemba South', +'TZ-02' => 'Tanwzania: Pwani', +'TZ-24' => 'Tanwzania: Rukwa', +'TZ-14' => 'Tanwzania: Ruvuma', +'TZ-15' => 'Tanwzania: Shinyanga', +'TZ-16' => 'Tanwzania: Singida', +'TZ-17' => 'Tanwzania: Tabora', +'TZ-18' => 'Tanwzania: Tanga', +'TZ-21' => 'Tanwzania: Zanzibar Central', +'TZ-22' => 'Tanwzania: Zanzibar North', +'TZ-25' => 'Tanwzania: Zanzibar Urban', + +'--TH' => '','-TH' => 'Thailand', +'TH-35' => 'Thailand: Ang Thong', +'TH-28' => 'Thailand: Buriram', +'TH-44' => 'Thailand: Chachoengsao', +'TH-32' => 'Thailand: Chai Nat', +'TH-26' => 'Thailand: Chaiyaphum', +'TH-48' => 'Thailand: Chanthaburi', +'TH-02' => 'Thailand: Chiang Mai', +'TH-03' => 'Thailand: Chiang Rai', +'TH-46' => 'Thailand: Chon Buri', +'TH-58' => 'Thailand: Chumphon', +'TH-23' => 'Thailand: Kalasin', +'TH-11' => 'Thailand: Kamphaeng Phet', +'TH-50' => 'Thailand: Kanchanaburi', +'TH-22' => 'Thailand: Khon Kaen', +'TH-63' => 'Thailand: Krabi', +'TH-40' => 'Thailand: Krung Thep', +'TH-06' => 'Thailand: Lampang', +'TH-05' => 'Thailand: Lamphun', +'TH-18' => 'Thailand: Loei', +'TH-34' => 'Thailand: Lop Buri', +'TH-01' => 'Thailand: Mae Hong Son', +'TH-24' => 'Thailand: Maha Sarakham', +'TH-78' => 'Thailand: Mukdahan', +'TH-43' => 'Thailand: Nakhon Nayok', +'TH-53' => 'Thailand: Nakhon Pathom', +'TH-21' => 'Thailand: Nakhon Phanom', +'TH-27' => 'Thailand: Nakhon Ratchasima', +'TH-16' => 'Thailand: Nakhon Sawan', +'TH-64' => 'Thailand: Nakhon Si Thammarat', +'TH-04' => 'Thailand: Nan', +'TH-31' => 'Thailand: Narathiwat', +'TH-17' => 'Thailand: Nong Khai', +'TH-38' => 'Thailand: Nonthaburi', +'TH-39' => 'Thailand: Pathum Thani', +'TH-69' => 'Thailand: Pattani', +'TH-61' => 'Thailand: Phangnga', +'TH-66' => 'Thailand: Phatthalung', +'TH-41' => 'Thailand: Phayao', +'TH-14' => 'Thailand: Phetchabun', +'TH-56' => 'Thailand: Phetchaburi', +'TH-13' => 'Thailand: Phichit', +'TH-12' => 'Thailand: Phitsanulok', +'TH-36' => 'Thailand: Phra Nakhon Si Ayutthaya', +'TH-07' => 'Thailand: Phrae', +'TH-62' => 'Thailand: Phuket', +'TH-45' => 'Thailand: Prachin Buri', +'TH-57' => 'Thailand: Prachuap Khiri Khan', +'TH-59' => 'Thailand: Ranong', +'TH-52' => 'Thailand: Ratchaburi', +'TH-47' => 'Thailand: Rayong', +'TH-25' => 'Thailand: Roi Et', +'TH-20' => 'Thailand: Sakon Nakhon', +'TH-42' => 'Thailand: Samut Prakan', +'TH-55' => 'Thailand: Samut Sakhon', +'TH-54' => 'Thailand: Samut Songkhram', +'TH-37' => 'Thailand: Saraburi', +'TH-67' => 'Thailand: Satun', +'TH-33' => 'Thailand: Sing Buri', +'TH-30' => 'Thailand: Sisaket', +'TH-68' => 'Thailand: Songkhla', +'TH-09' => 'Thailand: Sukhothai', +'TH-51' => 'Thailand: Suphan Buri', +'TH-60' => 'Thailand: Surat Thani', +'TH-29' => 'Thailand: Surin', +'TH-08' => 'Thailand: Tak', +'TH-65' => 'Thailand: Trang', +'TH-49' => 'Thailand: Trat', +'TH-75' => 'Thailand: Ubon Ratchathani', +'TH-76' => 'Thailand: Udon Thani', +'TH-15' => 'Thailand: Uthai Thani', +'TH-10' => 'Thailand: Uttaradit', +'TH-70' => 'Thailand: Yala', +'TH-72' => 'Thailand: Yasothon', + +'--TG' => '','-TG' => 'Togo', +'TG-01' => 'Togo: Amlame', +'TG-02' => 'Togo: Aneho', +'TG-03' => 'Togo: Atakpame', +'TG-15' => 'Togo: Badou', +'TG-04' => 'Togo: Bafilo', +'TG-05' => 'Togo: Bassar', +'TG-06' => 'Togo: Dapaong', +'TG-07' => 'Togo: Kante', +'TG-08' => 'Togo: Klouto', +'TG-14' => 'Togo: Kpagouda', +'TG-09' => 'Togo: Lama-Kara', +'TG-10' => 'Togo: Lome', +'TG-11' => 'Togo: Mango', +'TG-12' => 'Togo: Niamtougou', +'TG-13' => 'Togo: Notse', +'TG-16' => 'Togo: Sotouboua', +'TG-17' => 'Togo: Tabligbo', +'TG-19' => 'Togo: Tchamba', +'TG-20' => 'Togo: Tchaoudjo', +'TG-18' => 'Togo: Tsevie', +'TG-21' => 'Togo: Vogan', + +'--TO' => '','-TO' => 'Tonga', +'TO-01' => 'Tonga: Ha', +'TO-02' => 'Tonga: Tongatapu', +'TO-03' => 'Tonga: Vava', + +'--TT' => '','-TT' => 'Trinidad and Tobago', +'TT-01' => 'Trinidad and Tobago: Arima', +'TT-02' => 'Trinidad and Tobago: Caroni', +'TT-03' => 'Trinidad and Tobago: Mayaro', +'TT-04' => 'Trinidad and Tobago: Nariva', +'TT-05' => 'Trinidad and Tobago: Port-of-Spain', +'TT-06' => 'Trinidad and Tobago: Saint Andrew', +'TT-07' => 'Trinidad and Tobago: Saint David', +'TT-08' => 'Trinidad and Tobago: Saint George', +'TT-09' => 'Trinidad and Tobago: Saint Patrick', +'TT-10' => 'Trinidad and Tobago: San Fernando', +'TT-11' => 'Trinidad and Tobago: Tobago', +'TT-12' => 'Trinidad and Tobago: Victoria', + +'--TN' => '','-TN' => 'Tunisia', +'TN-15' => 'Tunisia: Al Mahdiyah', +'TN-16' => 'Tunisia: Al Munastir', +'TN-02' => 'Tunisia: Al Qasrayn', +'TN-03' => 'Tunisia: Al Qayrawan', +'TN-38' => 'Tunisia: Ariana', +'TN-17' => 'Tunisia: Bajah', +'TN-18' => 'Tunisia: Banzart', +'TN-27' => 'Tunisia: Bin', +'TN-06' => 'Tunisia: Jundubah', +'TN-14' => 'Tunisia: Kef', +'TN-28' => 'Tunisia: Madanin', +'TN-39' => 'Tunisia: Manouba', +'TN-19' => 'Tunisia: Nabul', +'TN-29' => 'Tunisia: Qabis', +'TN-10' => 'Tunisia: Qafsah', +'TN-31' => 'Tunisia: Qibili', +'TN-32' => 'Tunisia: Safaqis', +'TN-33' => 'Tunisia: Sidi Bu Zayd', +'TN-22' => 'Tunisia: Silyanah', +'TN-23' => 'Tunisia: Susah', +'TN-34' => 'Tunisia: Tatawin', +'TN-35' => 'Tunisia: Tawzar', +'TN-36' => 'Tunisia: Tunis', +'TN-37' => 'Tunisia: Zaghwan', + +'--TR' => '','-TR' => 'Turkey', +'TR-81' => 'Turkey: Adana', +'TR-02' => 'Turkey: Adiyaman', +'TR-03' => 'Turkey: Afyon', +'TR-04' => 'Turkey: Agri', +'TR-75' => 'Turkey: Aksaray', +'TR-05' => 'Turkey: Amasya', +'TR-68' => 'Turkey: Ankara', +'TR-07' => 'Turkey: Antalya', +'TR-86' => 'Turkey: Ardahan', +'TR-08' => 'Turkey: Artvin', +'TR-09' => 'Turkey: Aydin', +'TR-10' => 'Turkey: Balikesir', +'TR-87' => 'Turkey: Bartin', +'TR-76' => 'Turkey: Batman', +'TR-77' => 'Turkey: Bayburt', +'TR-11' => 'Turkey: Bilecik', +'TR-12' => 'Turkey: Bingol', +'TR-13' => 'Turkey: Bitlis', +'TR-14' => 'Turkey: Bolu', +'TR-15' => 'Turkey: Burdur', +'TR-16' => 'Turkey: Bursa', +'TR-17' => 'Turkey: Canakkale', +'TR-82' => 'Turkey: Cankiri', +'TR-19' => 'Turkey: Corum', +'TR-20' => 'Turkey: Denizli', +'TR-21' => 'Turkey: Diyarbakir', +'TR-93' => 'Turkey: Duzce', +'TR-22' => 'Turkey: Edirne', +'TR-23' => 'Turkey: Elazig', +'TR-24' => 'Turkey: Erzincan', +'TR-25' => 'Turkey: Erzurum', +'TR-26' => 'Turkey: Eskisehir', +'TR-83' => 'Turkey: Gaziantep', +'TR-28' => 'Turkey: Giresun', +'TR-69' => 'Turkey: Gumushane', +'TR-70' => 'Turkey: Hakkari', +'TR-31' => 'Turkey: Hatay', +'TR-32' => 'Turkey: Icel', +'TR-88' => 'Turkey: Igdir', +'TR-33' => 'Turkey: Isparta', +'TR-34' => 'Turkey: Istanbul', +'TR-35' => 'Turkey: Izmir', +'TR-46' => 'Turkey: Kahramanmaras', +'TR-89' => 'Turkey: Karabuk', +'TR-78' => 'Turkey: Karaman', +'TR-84' => 'Turkey: Kars', +'TR-37' => 'Turkey: Kastamonu', +'TR-38' => 'Turkey: Kayseri', +'TR-90' => 'Turkey: Kilis', +'TR-79' => 'Turkey: Kirikkale', +'TR-39' => 'Turkey: Kirklareli', +'TR-40' => 'Turkey: Kirsehir', +'TR-41' => 'Turkey: Kocaeli', +'TR-71' => 'Turkey: Konya', +'TR-43' => 'Turkey: Kutahya', +'TR-44' => 'Turkey: Malatya', +'TR-45' => 'Turkey: Manisa', +'TR-72' => 'Turkey: Mardin', +'TR-48' => 'Turkey: Mugla', +'TR-49' => 'Turkey: Mus', +'TR-50' => 'Turkey: Nevsehir', +'TR-73' => 'Turkey: Nigde', +'TR-52' => 'Turkey: Ordu', +'TR-91' => 'Turkey: Osmaniye', +'TR-53' => 'Turkey: Rize', +'TR-54' => 'Turkey: Sakarya', +'TR-55' => 'Turkey: Samsun', +'TR-63' => 'Turkey: Sanliurfa', +'TR-74' => 'Turkey: Siirt', +'TR-57' => 'Turkey: Sinop', +'TR-80' => 'Turkey: Sirnak', +'TR-58' => 'Turkey: Sivas', +'TR-59' => 'Turkey: Tekirdag', +'TR-60' => 'Turkey: Tokat', +'TR-61' => 'Turkey: Trabzon', +'TR-62' => 'Turkey: Tunceli', +'TR-64' => 'Turkey: Usak', +'TR-65' => 'Turkey: Van', +'TR-92' => 'Turkey: Yalova', +'TR-66' => 'Turkey: Yozgat', +'TR-85' => 'Turkey: Zonguldak', + +'--TM' => '','-TM' => 'Turkmenistan', +'TM-01' => 'Turkmenistan: Ahal', +'TM-02' => 'Turkmenistan: Balkan', +'TM-03' => 'Turkmenistan: Dashoguz', +'TM-04' => 'Turkmenistan: Lebap', +'TM-05' => 'Turkmenistan: Mary', + +'--UG' => '','-UG' => 'Uganda', +'UG-65' => 'Uganda: Adjumani', +'UG-77' => 'Uganda: Arua', +'UG-66' => 'Uganda: Bugiri', +'UG-67' => 'Uganda: Busia', +'UG-05' => 'Uganda: Busoga', +'UG-18' => 'Uganda: Central', +'UG-20' => 'Uganda: Eastern', +'UG-78' => 'Uganda: Iganga', +'UG-79' => 'Uganda: Kabarole', +'UG-80' => 'Uganda: Kaberamaido', +'UG-37' => 'Uganda: Kampala', +'UG-81' => 'Uganda: Kamwenge', +'UG-82' => 'Uganda: Kanungu', +'UG-08' => 'Uganda: Karamoja', +'UG-69' => 'Uganda: Katakwi', +'UG-83' => 'Uganda: Kayunga', +'UG-84' => 'Uganda: Kitgum', +'UG-85' => 'Uganda: Kyenjojo', +'UG-86' => 'Uganda: Mayuge', +'UG-87' => 'Uganda: Mbale', +'UG-88' => 'Uganda: Moroto', +'UG-89' => 'Uganda: Mpigi', +'UG-90' => 'Uganda: Mukono', +'UG-91' => 'Uganda: Nakapiripirit', +'UG-73' => 'Uganda: Nakasongola', +'UG-21' => 'Uganda: Nile', +'UG-22' => 'Uganda: North Buganda', +'UG-23' => 'Uganda: Northern', +'UG-92' => 'Uganda: Pader', +'UG-93' => 'Uganda: Rukungiri', +'UG-74' => 'Uganda: Sembabule', +'UG-94' => 'Uganda: Sironko', +'UG-95' => 'Uganda: Soroti', +'UG-12' => 'Uganda: South Buganda', +'UG-24' => 'Uganda: Southern', +'UG-96' => 'Uganda: Wakiso', +'UG-25' => 'Uganda: Western', +'UG-97' => 'Uganda: Yumbe', + +'--UA' => '','-UA' => 'Ukraine', +'UA-01' => 'Ukraine: Cherkas\'ka Oblast\'', +'UA-02' => 'Ukraine: Chernihivs\'ka Oblast\'', +'UA-03' => 'Ukraine: Chernivets\'ka Oblast\'', +'UA-04' => 'Ukraine: Dnipropetrovs\'ka Oblast\'', +'UA-05' => 'Ukraine: Donets\'ka Oblast\'', +'UA-06' => 'Ukraine: Ivano-Frankivs\'ka Oblast\'', +'UA-07' => 'Ukraine: Kharkivs\'ka Oblast\'', +'UA-08' => 'Ukraine: Khersons\'ka Oblast\'', +'UA-09' => 'Ukraine: Khmel\'nyts\'ka Oblast\'', +'UA-10' => 'Ukraine: Kirovohrads\'ka Oblast\'', +'UA-11' => 'Ukraine: Krym', +'UA-12' => 'Ukraine: Kyyiv', +'UA-13' => 'Ukraine: Kyyivs\'ka Oblast\'', +'UA-14' => 'Ukraine: Luhans\'ka Oblast\'', +'UA-15' => 'Ukraine: L\'vivs\'ka Oblast\'', +'UA-16' => 'Ukraine: Mykolayivs\'ka Oblast\'', +'UA-17' => 'Ukraine: Odes\'ka Oblast\'', +'UA-18' => 'Ukraine: Poltavs\'ka Oblast\'', +'UA-19' => 'Ukraine: Rivnens\'ka Oblast\'', +'UA-20' => 'Ukraine: Sevastopol\'', +'UA-21' => 'Ukraine: Sums\'ka Oblast\'', +'UA-22' => 'Ukraine: Ternopil\'s\'ka Oblast\'', +'UA-23' => 'Ukraine: Vinnyts\'ka Oblast\'', +'UA-24' => 'Ukraine: Volyns\'ka Oblast\'', +'UA-25' => 'Ukraine: Zakarpats\'ka Oblast\'', +'UA-26' => 'Ukraine: Zaporiz\'ka Oblast\'', +'UA-27' => 'Ukraine: Zhytomyrs\'ka Oblast\'', + +'--AE' => '','-AE' => 'United Arab Emirates', +'AE-01' => 'United Arab Emirates: Abu Dhabi', +'AE-02' => 'United Arab Emirates: Ajman', +'AE-03' => 'United Arab Emirates: Dubai', +'AE-04' => 'United Arab Emirates: Fujairah', +'AE-05' => 'United Arab Emirates: Ras Al Khaimah', +'AE-06' => 'United Arab Emirates: Sharjah', +'AE-07' => 'United Arab Emirates: Umm Al Quwain', + +'--GB' => '','-GB' => 'United Kingdom', +'GB-T5' => 'United Kingdom: Aberdeen City', +'GB-T6' => 'United Kingdom: Aberdeenshire', +'GB-T7' => 'United Kingdom: Angus', +'GB-Q6' => 'United Kingdom: Antrim', +'GB-Q7' => 'United Kingdom: Ards', +'GB-T8' => 'United Kingdom: Argyll and Bute', +'GB-Q8' => 'United Kingdom: Armagh', +'GB-01' => 'United Kingdom: Avon', +'GB-Q9' => 'United Kingdom: Ballymena', +'GB-R1' => 'United Kingdom: Ballymoney', +'GB-R2' => 'United Kingdom: Banbridge', +'GB-A1' => 'United Kingdom: Barking and Dagenham', +'GB-A2' => 'United Kingdom: Barnet', +'GB-A3' => 'United Kingdom: Barnsley', +'GB-A4' => 'United Kingdom: Bath and North East Somerset', +'GB-A5' => 'United Kingdom: Bedfordshire', +'GB-R3' => 'United Kingdom: Belfast', +'GB-03' => 'United Kingdom: Berkshire', +'GB-A6' => 'United Kingdom: Bexley', +'GB-A7' => 'United Kingdom: Birmingham', +'GB-A8' => 'United Kingdom: Blackburn with Darwen', +'GB-A9' => 'United Kingdom: Blackpool', +'GB-X2' => 'United Kingdom: Blaenau Gwent', +'GB-B1' => 'United Kingdom: Bolton', +'GB-B2' => 'United Kingdom: Bournemouth', +'GB-B3' => 'United Kingdom: Bracknell Forest', +'GB-B4' => 'United Kingdom: Bradford', +'GB-B5' => 'United Kingdom: Brent', +'GB-X3' => 'United Kingdom: Bridgend', +'GB-B6' => 'United Kingdom: Brighton and Hove', +'GB-B7' => 'United Kingdom: Bristol', +'GB-B8' => 'United Kingdom: Bromley', +'GB-B9' => 'United Kingdom: Buckinghamshire', +'GB-C1' => 'United Kingdom: Bury', +'GB-X4' => 'United Kingdom: Caerphilly', +'GB-C2' => 'United Kingdom: Calderdale', +'GB-C3' => 'United Kingdom: Cambridgeshire', +'GB-C4' => 'United Kingdom: Camden', +'GB-X5' => 'United Kingdom: Cardiff', +'GB-X7' => 'United Kingdom: Carmarthenshire', +'GB-R4' => 'United Kingdom: Carrickfergus', +'GB-R5' => 'United Kingdom: Castlereagh', +'GB-79' => 'United Kingdom: Central', +'GB-X6' => 'United Kingdom: Ceredigion', +'GB-C5' => 'United Kingdom: Cheshire', +'GB-U1' => 'United Kingdom: Clackmannanshire', +'GB-07' => 'United Kingdom: Cleveland', +'GB-90' => 'United Kingdom: Clwyd', +'GB-R6' => 'United Kingdom: Coleraine', +'GB-X8' => 'United Kingdom: Conwy', +'GB-R7' => 'United Kingdom: Cookstown', +'GB-C6' => 'United Kingdom: Cornwall', +'GB-C7' => 'United Kingdom: Coventry', +'GB-R8' => 'United Kingdom: Craigavon', +'GB-C8' => 'United Kingdom: Croydon', +'GB-C9' => 'United Kingdom: Cumbria', +'GB-D1' => 'United Kingdom: Darlington', +'GB-X9' => 'United Kingdom: Denbighshire', +'GB-D2' => 'United Kingdom: Derby', +'GB-D3' => 'United Kingdom: Derbyshire', +'GB-S6' => 'United Kingdom: Derry', +'GB-D4' => 'United Kingdom: Devon', +'GB-D5' => 'United Kingdom: Doncaster', +'GB-D6' => 'United Kingdom: Dorset', +'GB-R9' => 'United Kingdom: Down', +'GB-D7' => 'United Kingdom: Dudley', +'GB-U2' => 'United Kingdom: Dumfries and Galloway', +'GB-U3' => 'United Kingdom: Dundee City', +'GB-S1' => 'United Kingdom: Dungannon', +'GB-D8' => 'United Kingdom: Durham', +'GB-91' => 'United Kingdom: Dyfed', +'GB-D9' => 'United Kingdom: Ealing', +'GB-U4' => 'United Kingdom: East Ayrshire', +'GB-U5' => 'United Kingdom: East Dunbartonshire', +'GB-U6' => 'United Kingdom: East Lothian', +'GB-U7' => 'United Kingdom: East Renfrewshire', +'GB-E1' => 'United Kingdom: East Riding of Yorkshire', +'GB-E2' => 'United Kingdom: East Sussex', +'GB-U8' => 'United Kingdom: Edinburgh', +'GB-W8' => 'United Kingdom: Eilean Siar', +'GB-E3' => 'United Kingdom: Enfield', +'GB-E4' => 'United Kingdom: Essex', +'GB-U9' => 'United Kingdom: Falkirk', +'GB-S2' => 'United Kingdom: Fermanagh', +'GB-V1' => 'United Kingdom: Fife', +'GB-Y1' => 'United Kingdom: Flintshire', +'GB-E5' => 'United Kingdom: Gateshead', +'GB-V2' => 'United Kingdom: Glasgow City', +'GB-E6' => 'United Kingdom: Gloucestershire', +'GB-82' => 'United Kingdom: Grampian', +'GB-17' => 'United Kingdom: Greater London', +'GB-18' => 'United Kingdom: Greater Manchester', +'GB-E7' => 'United Kingdom: Greenwich', +'GB-92' => 'United Kingdom: Gwent', +'GB-Y2' => 'United Kingdom: Gwynedd', +'GB-E8' => 'United Kingdom: Hackney', +'GB-E9' => 'United Kingdom: Halton', +'GB-F1' => 'United Kingdom: Hammersmith and Fulham', +'GB-F2' => 'United Kingdom: Hampshire', +'GB-F3' => 'United Kingdom: Haringey', +'GB-F4' => 'United Kingdom: Harrow', +'GB-F5' => 'United Kingdom: Hartlepool', +'GB-F6' => 'United Kingdom: Havering', +'GB-20' => 'United Kingdom: Hereford and Worcester', +'GB-F7' => 'United Kingdom: Herefordshire', +'GB-F8' => 'United Kingdom: Hertford', +'GB-V3' => 'United Kingdom: Highland', +'GB-F9' => 'United Kingdom: Hillingdon', +'GB-G1' => 'United Kingdom: Hounslow', +'GB-22' => 'United Kingdom: Humberside', +'GB-V4' => 'United Kingdom: Inverclyde', +'GB-X1' => 'United Kingdom: Isle of Anglesey', +'GB-G2' => 'United Kingdom: Isle of Wight', +'GB-G3' => 'United Kingdom: Islington', +'GB-G4' => 'United Kingdom: Kensington and Chelsea', +'GB-G5' => 'United Kingdom: Kent', +'GB-G6' => 'United Kingdom: Kingston upon Hull', +'GB-G7' => 'United Kingdom: Kingston upon Thames', +'GB-G8' => 'United Kingdom: Kirklees', +'GB-G9' => 'United Kingdom: Knowsley', +'GB-H1' => 'United Kingdom: Lambeth', +'GB-H2' => 'United Kingdom: Lancashire', +'GB-S3' => 'United Kingdom: Larne', +'GB-H3' => 'United Kingdom: Leeds', +'GB-H4' => 'United Kingdom: Leicester', +'GB-H5' => 'United Kingdom: Leicestershire', +'GB-H6' => 'United Kingdom: Lewisham', +'GB-S4' => 'United Kingdom: Limavady', +'GB-H7' => 'United Kingdom: Lincolnshire', +'GB-S5' => 'United Kingdom: Lisburn', +'GB-H8' => 'United Kingdom: Liverpool', +'GB-H9' => 'United Kingdom: London', +'GB-84' => 'United Kingdom: Lothian', +'GB-I1' => 'United Kingdom: Luton', +'GB-S7' => 'United Kingdom: Magherafelt', +'GB-I2' => 'United Kingdom: Manchester', +'GB-I3' => 'United Kingdom: Medway', +'GB-28' => 'United Kingdom: Merseyside', +'GB-Y3' => 'United Kingdom: Merthyr Tydfil', +'GB-I4' => 'United Kingdom: Merton', +'GB-94' => 'United Kingdom: Mid Glamorgan', +'GB-I5' => 'United Kingdom: Middlesbrough', +'GB-V5' => 'United Kingdom: Midlothian', +'GB-I6' => 'United Kingdom: Milton Keynes', +'GB-Y4' => 'United Kingdom: Monmouthshire', +'GB-V6' => 'United Kingdom: Moray', +'GB-S8' => 'United Kingdom: Moyle', +'GB-Y5' => 'United Kingdom: Neath Port Talbot', +'GB-I7' => 'United Kingdom: Newcastle upon Tyne', +'GB-I8' => 'United Kingdom: Newham', +'GB-Y6' => 'United Kingdom: Newport', +'GB-S9' => 'United Kingdom: Newry and Mourne', +'GB-T1' => 'United Kingdom: Newtownabbey', +'GB-I9' => 'United Kingdom: Norfolk', +'GB-V7' => 'United Kingdom: North Ayrshire', +'GB-T2' => 'United Kingdom: North Down', +'GB-J2' => 'United Kingdom: North East Lincolnshire', +'GB-V8' => 'United Kingdom: North Lanarkshire', +'GB-J3' => 'United Kingdom: North Lincolnshire', +'GB-J4' => 'United Kingdom: North Somerset', +'GB-J5' => 'United Kingdom: North Tyneside', +'GB-J7' => 'United Kingdom: North Yorkshire', +'GB-J1' => 'United Kingdom: Northamptonshire', +'GB-J6' => 'United Kingdom: Northumberland', +'GB-J8' => 'United Kingdom: Nottingham', +'GB-J9' => 'United Kingdom: Nottinghamshire', +'GB-K1' => 'United Kingdom: Oldham', +'GB-T3' => 'United Kingdom: Omagh', +'GB-V9' => 'United Kingdom: Orkney', +'GB-K2' => 'United Kingdom: Oxfordshire', +'GB-Y7' => 'United Kingdom: Pembrokeshire', +'GB-W1' => 'United Kingdom: Perth and Kinross', +'GB-K3' => 'United Kingdom: Peterborough', +'GB-K4' => 'United Kingdom: Plymouth', +'GB-K5' => 'United Kingdom: Poole', +'GB-K6' => 'United Kingdom: Portsmouth', +'GB-Y8' => 'United Kingdom: Powys', +'GB-K7' => 'United Kingdom: Reading', +'GB-K8' => 'United Kingdom: Redbridge', +'GB-K9' => 'United Kingdom: Redcar and Cleveland', +'GB-W2' => 'United Kingdom: Renfrewshire', +'GB-Y9' => 'United Kingdom: Rhondda Cynon Taff', +'GB-L1' => 'United Kingdom: Richmond upon Thames', +'GB-L2' => 'United Kingdom: Rochdale', +'GB-L3' => 'United Kingdom: Rotherham', +'GB-L4' => 'United Kingdom: Rutland', +'GB-L5' => 'United Kingdom: Salford', +'GB-L7' => 'United Kingdom: Sandwell', +'GB-T9' => 'United Kingdom: Scottish Borders', +'GB-L8' => 'United Kingdom: Sefton', +'GB-L9' => 'United Kingdom: Sheffield', +'GB-W3' => 'United Kingdom: Shetland Islands', +'GB-L6' => 'United Kingdom: Shropshire', +'GB-M1' => 'United Kingdom: Slough', +'GB-M2' => 'United Kingdom: Solihull', +'GB-M3' => 'United Kingdom: Somerset', +'GB-W4' => 'United Kingdom: South Ayrshire', +'GB-96' => 'United Kingdom: South Glamorgan', +'GB-M6' => 'United Kingdom: South Gloucestershire', +'GB-W5' => 'United Kingdom: South Lanarkshire', +'GB-M7' => 'United Kingdom: South Tyneside', +'GB-37' => 'United Kingdom: South Yorkshire', +'GB-M4' => 'United Kingdom: Southampton', +'GB-M5' => 'United Kingdom: Southend-on-Sea', +'GB-M8' => 'United Kingdom: Southwark', +'GB-N1' => 'United Kingdom: St. Helens', +'GB-M9' => 'United Kingdom: Staffordshire', +'GB-W6' => 'United Kingdom: Stirling', +'GB-N2' => 'United Kingdom: Stockport', +'GB-N3' => 'United Kingdom: Stockton-on-Tees', +'GB-N4' => 'United Kingdom: Stoke-on-Trent', +'GB-T4' => 'United Kingdom: Strabane', +'GB-87' => 'United Kingdom: Strathclyde', +'GB-N5' => 'United Kingdom: Suffolk', +'GB-N6' => 'United Kingdom: Sunderland', +'GB-N7' => 'United Kingdom: Surrey', +'GB-N8' => 'United Kingdom: Sutton', +'GB-Z1' => 'United Kingdom: Swansea', +'GB-N9' => 'United Kingdom: Swindon', +'GB-O1' => 'United Kingdom: Tameside', +'GB-88' => 'United Kingdom: Tayside', +'GB-O2' => 'United Kingdom: Telford and Wrekin', +'GB-O3' => 'United Kingdom: Thurrock', +'GB-O4' => 'United Kingdom: Torbay', +'GB-Z2' => 'United Kingdom: Torfaen', +'GB-O5' => 'United Kingdom: Tower Hamlets', +'GB-O6' => 'United Kingdom: Trafford', +'GB-41' => 'United Kingdom: Tyne and Wear', +'GB-Z3' => 'United Kingdom: Vale of Glamorgan', +'GB-O7' => 'United Kingdom: Wakefield', +'GB-O8' => 'United Kingdom: Walsall', +'GB-O9' => 'United Kingdom: Waltham Forest', +'GB-P1' => 'United Kingdom: Wandsworth', +'GB-P2' => 'United Kingdom: Warrington', +'GB-P3' => 'United Kingdom: Warwickshire', +'GB-P4' => 'United Kingdom: West Berkshire', +'GB-W7' => 'United Kingdom: West Dunbartonshire', +'GB-97' => 'United Kingdom: West Glamorgan', +'GB-W9' => 'United Kingdom: West Lothian', +'GB-43' => 'United Kingdom: West Midlands', +'GB-P6' => 'United Kingdom: West Sussex', +'GB-45' => 'United Kingdom: West Yorkshire', +'GB-P5' => 'United Kingdom: Westminster', +'GB-P7' => 'United Kingdom: Wigan', +'GB-P8' => 'United Kingdom: Wiltshire', +'GB-P9' => 'United Kingdom: Windsor and Maidenhead', +'GB-Q1' => 'United Kingdom: Wirral', +'GB-Q2' => 'United Kingdom: Wokingham', +'GB-Q3' => 'United Kingdom: Wolverhampton', +'GB-Q4' => 'United Kingdom: Worcestershire', +'GB-Z4' => 'United Kingdom: Wrexham', +'GB-Q5' => 'United Kingdom: York', + +'--US' => '','-US' => 'United States', +'US-AL' => 'United States: Alabama', +'US-AK' => 'United States: Alaska', +'US-AS' => 'United States: American Samoa', +'US-AZ' => 'United States: Arizona', +'US-AR' => 'United States: Arkansas', +'US-AA' => 'United States: Armed Forces Americas', +'US-AE' => 'United States: Armed Forces Europe', +'US-AP' => 'United States: Armed Forces Pacific', +'US-CA' => 'United States: California', +'US-CO' => 'United States: Colorado', +'US-CT' => 'United States: Connecticut', +'US-DE' => 'United States: Delaware', +'US-DC' => 'United States: District of Columbia', +'US-FM' => 'United States: Federated States of Micronesia', +'US-FL' => 'United States: Florida', +'US-GA' => 'United States: Georgia', +'US-GU' => 'United States: Guam', +'US-HI' => 'United States: Hawaii', +'US-ID' => 'United States: Idaho', +'US-IL' => 'United States: Illinois', +'US-IN' => 'United States: Indiana', +'US-IA' => 'United States: Iowa', +'US-KS' => 'United States: Kansas', +'US-KY' => 'United States: Kentucky', +'US-LA' => 'United States: Louisiana', +'US-ME' => 'United States: Maine', +'US-MH' => 'United States: Marshall Islands', +'US-MD' => 'United States: Maryland', +'US-MA' => 'United States: Massachusetts', +'US-MI' => 'United States: Michigan', +'US-MN' => 'United States: Minnesota', +'US-MS' => 'United States: Mississippi', +'US-MO' => 'United States: Missouri', +'US-MT' => 'United States: Montana', +'US-NE' => 'United States: Nebraska', +'US-NV' => 'United States: Nevada', +'US-NH' => 'United States: New Hampshire', +'US-NJ' => 'United States: New Jersey', +'US-NM' => 'United States: New Mexico', +'US-NY' => 'United States: New York', +'US-NC' => 'United States: North Carolina', +'US-ND' => 'United States: North Dakota', +'US-MP' => 'United States: Northern Mariana Islands', +'US-OH' => 'United States: Ohio', +'US-OK' => 'United States: Oklahoma', +'US-OR' => 'United States: Oregon', +'US-PW' => 'United States: Palau', +'US-PA' => 'United States: Pennsylvania', +'US-PR' => 'United States: Puerto Rico', +'US-RI' => 'United States: Rhode Island', +'US-SC' => 'United States: South Carolina', +'US-SD' => 'United States: South Dakota', +'US-TN' => 'United States: Tennessee', +'US-TX' => 'United States: Texas', +'US-UT' => 'United States: Utah', +'US-VT' => 'United States: Vermont', +'US-VI' => 'United States: Virgin Islands', +'US-VA' => 'United States: Virginia', +'US-WA' => 'United States: Washington', +'US-WV' => 'United States: West Virginia', +'US-WI' => 'United States: Wisconsin', +'US-WY' => 'United States: Wyoming', + +'--UY' => '','-UY' => 'Uruguay', +'UY-01' => 'Uruguay: Artigas', +'UY-02' => 'Uruguay: Canelones', +'UY-03' => 'Uruguay: Cerro Largo', +'UY-04' => 'Uruguay: Colonia', +'UY-05' => 'Uruguay: Durazno', +'UY-06' => 'Uruguay: Flores', +'UY-07' => 'Uruguay: Florida', +'UY-08' => 'Uruguay: Lavalleja', +'UY-09' => 'Uruguay: Maldonado', +'UY-10' => 'Uruguay: Montevideo', +'UY-11' => 'Uruguay: Paysandu', +'UY-12' => 'Uruguay: Rio Negro', +'UY-13' => 'Uruguay: Rivera', +'UY-14' => 'Uruguay: Rocha', +'UY-15' => 'Uruguay: Salto', +'UY-16' => 'Uruguay: San Jose', +'UY-17' => 'Uruguay: Soriano', +'UY-18' => 'Uruguay: Tacuarembo', +'UY-19' => 'Uruguay: Treinta y Tres', + +'--UZ' => '','-UZ' => 'Uzbekistan', +'UZ-01' => 'Uzbekistan: Andijon', +'UZ-02' => 'Uzbekistan: Bukhoro', +'UZ-03' => 'Uzbekistan: Farghona', +'UZ-04' => 'Uzbekistan: Jizzakh', +'UZ-05' => 'Uzbekistan: Khorazm', +'UZ-06' => 'Uzbekistan: Namangan', +'UZ-07' => 'Uzbekistan: Nawoiy', +'UZ-08' => 'Uzbekistan: Qashqadaryo', +'UZ-09' => 'Uzbekistan: Qoraqalpoghiston', +'UZ-10' => 'Uzbekistan: Samarqand', +'UZ-11' => 'Uzbekistan: Sirdaryo', +'UZ-12' => 'Uzbekistan: Surkhondaryo', +'UZ-13' => 'Uzbekistan: Toshkent', +'UZ-14' => 'Uzbekistan: Toshkent', + +'--VU' => '','-VU' => 'Vanuatu', +'VU-05' => 'Vanuatu: Ambrym', +'VU-06' => 'Vanuatu: Aoba', +'VU-08' => 'Vanuatu: Efate', +'VU-09' => 'Vanuatu: Epi', +'VU-10' => 'Vanuatu: Malakula', +'VU-16' => 'Vanuatu: Malampa', +'VU-11' => 'Vanuatu: Paama', +'VU-17' => 'Vanuatu: Penama', +'VU-12' => 'Vanuatu: Pentecote', +'VU-13' => 'Vanuatu: Sanma', +'VU-18' => 'Vanuatu: Shefa', +'VU-14' => 'Vanuatu: Shepherd', +'VU-15' => 'Vanuatu: Tafea', +'VU-07' => 'Vanuatu: Torba', + +'--VE' => '','-VE' => 'Venezuela', +'VE-01' => 'Venezuela: Amazonas', +'VE-02' => 'Venezuela: Anzoategui', +'VE-03' => 'Venezuela: Apure', +'VE-04' => 'Venezuela: Aragua', +'VE-05' => 'Venezuela: Barinas', +'VE-06' => 'Venezuela: Bolivar', +'VE-07' => 'Venezuela: Carabobo', +'VE-08' => 'Venezuela: Cojedes', +'VE-09' => 'Venezuela: Delta Amacuro', +'VE-24' => 'Venezuela: Dependencias Federales', +'VE-25' => 'Venezuela: Distrito Federal', +'VE-11' => 'Venezuela: Falcon', +'VE-12' => 'Venezuela: Guarico', +'VE-13' => 'Venezuela: Lara', +'VE-14' => 'Venezuela: Merida', +'VE-15' => 'Venezuela: Miranda', +'VE-16' => 'Venezuela: Monagas', +'VE-17' => 'Venezuela: Nueva Esparta', +'VE-18' => 'Venezuela: Portuguesa', +'VE-19' => 'Venezuela: Sucre', +'VE-20' => 'Venezuela: Tachira', +'VE-21' => 'Venezuela: Trujillo', +'VE-26' => 'Venezuela: Vargas', +'VE-22' => 'Venezuela: Yaracuy', +'VE-23' => 'Venezuela: Zulia', + +'--VN' => '','-VN' => 'Vietnam', +'VN-43' => 'Vietnam: An Giang', +'VN-53' => 'Vietnam: Ba Ria-Vung Tau', +'VN-02' => 'Vietnam: Bac Thai', +'VN-03' => 'Vietnam: Ben Tre', +'VN-54' => 'Vietnam: Binh Dinh', +'VN-55' => 'Vietnam: Binh Thuan', +'VN-56' => 'Vietnam: Can Tho', +'VN-05' => 'Vietnam: Cao Bang', +'VN-44' => 'Vietnam: Dac Lac', +'VN-45' => 'Vietnam: Dong Nai', +'VN-20' => 'Vietnam: Dong Nam Bo', +'VN-46' => 'Vietnam: Dong Thap', +'VN-57' => 'Vietnam: Gia Lai', +'VN-11' => 'Vietnam: Ha Bac', +'VN-58' => 'Vietnam: Ha Giang', +'VN-51' => 'Vietnam: Ha Noi', +'VN-59' => 'Vietnam: Ha Tay', +'VN-60' => 'Vietnam: Ha Tinh', +'VN-12' => 'Vietnam: Hai Hung', +'VN-13' => 'Vietnam: Hai Phong', +'VN-52' => 'Vietnam: Ho Chi Minh', +'VN-61' => 'Vietnam: Hoa Binh', +'VN-62' => 'Vietnam: Khanh Hoa', +'VN-47' => 'Vietnam: Kien Giang', +'VN-63' => 'Vietnam: Kon Tum', +'VN-22' => 'Vietnam: Lai Chau', +'VN-23' => 'Vietnam: Lam Dong', +'VN-39' => 'Vietnam: Lang Son', +'VN-64' => 'Vietnam: Lao Cai', +'VN-24' => 'Vietnam: Long An', +'VN-48' => 'Vietnam: Minh Hai', +'VN-65' => 'Vietnam: Nam Ha', +'VN-66' => 'Vietnam: Nghe An', +'VN-67' => 'Vietnam: Ninh Binh', +'VN-68' => 'Vietnam: Ninh Thuan', +'VN-69' => 'Vietnam: Phu Yen', +'VN-70' => 'Vietnam: Quang Binh', +'VN-29' => 'Vietnam: Quang Nam-Da Nang', +'VN-71' => 'Vietnam: Quang Ngai', +'VN-30' => 'Vietnam: Quang Ninh', +'VN-72' => 'Vietnam: Quang Tri', +'VN-73' => 'Vietnam: Soc Trang', +'VN-32' => 'Vietnam: Son La', +'VN-49' => 'Vietnam: Song Be', +'VN-33' => 'Vietnam: Tay Ninh', +'VN-35' => 'Vietnam: Thai Binh', +'VN-34' => 'Vietnam: Thanh Hoa', +'VN-74' => 'Vietnam: Thua Thien', +'VN-37' => 'Vietnam: Tien Giang', +'VN-75' => 'Vietnam: Tra Vinh', +'VN-76' => 'Vietnam: Tuyen Quang', +'VN-77' => 'Vietnam: Vinh Long', +'VN-50' => 'Vietnam: Vinh Phu', +'VN-78' => 'Vietnam: Yen Bai', + +'--YE' => '','-YE' => 'Yemen', +'YE-01' => 'Yemen: Abyan', +'YE-20' => 'Yemen: Al Bayda\'', +'YE-08' => 'Yemen: Al Hudaydah', +'YE-21' => 'Yemen: Al Jawf', +'YE-03' => 'Yemen: Al Mahrah', +'YE-10' => 'Yemen: Al Mahwit', +'YE-11' => 'Yemen: Dhamar', +'YE-04' => 'Yemen: Hadramawt', +'YE-22' => 'Yemen: Hajjah', +'YE-23' => 'Yemen: Ibb', +'YE-24' => 'Yemen: Lahij', +'YE-14' => 'Yemen: Ma\'rib', +'YE-15' => 'Yemen: Sa', +'YE-16' => 'Yemen: San', +'YE-05' => 'Yemen: Shabwah', +'YE-25' => 'Yemen: Ta', + +'--ZM' => '','-ZM' => 'Zambia', +'ZM-02' => 'Zambia: Central', +'ZM-08' => 'Zambia: Copperbelt', +'ZM-03' => 'Zambia: Eastern', +'ZM-04' => 'Zambia: Luapula', +'ZM-09' => 'Zambia: Lusaka', +'ZM-05' => 'Zambia: Northern', +'ZM-06' => 'Zambia: North-Western', +'ZM-07' => 'Zambia: Southern', +'ZM-01' => 'Zambia: Western', + +'--ZW' => '','-ZW' => 'Zimbabwe', +'ZW-09' => 'Zimbabwe: Bulawayo', +'ZW-10' => 'Zimbabwe: Harare', +'ZW-01' => 'Zimbabwe: Manicaland', +'ZW-03' => 'Zimbabwe: Mashonaland Central', +'ZW-04' => 'Zimbabwe: Mashonaland East', +'ZW-05' => 'Zimbabwe: Mashonaland West', +'ZW-08' => 'Zimbabwe: Masvingo', +'ZW-06' => 'Zimbabwe: Matabeleland North', +'ZW-07' => 'Zimbabwe: Matabeleland South', +'ZW-02' => 'Zimbabwe: Midlands\' + diff --git a/deployed/regularlabs/libraries/regularlabs/fields/showon.php b/deployed/regularlabs/libraries/regularlabs/fields/showon.php new file mode 100644 index 00000000..c91ae013 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/showon.php @@ -0,0 +1,48 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use RegularLabs\Library\ShowOn as RL_ShowOn; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_ShowOn extends \RegularLabs\Library\Field +{ + public $type = 'ShowOn'; + + protected function getLabel() + { + return ''; + } + + protected function getInput() + { + $value = (string) $this->get('value'); + $class = $this->get('class', ''); + $formControl = $this->get('form', $this->formControl); + $formControl = $formControl == 'root' ? '' : $formControl; + + if ( ! $value) + { + return RL_ShowOn::close(); + } + + return '' + . RL_ShowOn::open($value, $formControl, $this->group, $class) + . '
'; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/simplecategories.php b/deployed/regularlabs/libraries/regularlabs/fields/simplecategories.php new file mode 100644 index 00000000..3582e274 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/simplecategories.php @@ -0,0 +1,118 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\HTML\HTMLHelper as JHtml; +use Joomla\CMS\Language\Text as JText; +use RegularLabs\Library\Document as RL_Document; +use RegularLabs\Library\ShowOn as RL_ShowOn; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_SimpleCategories extends \RegularLabs\Library\Field +{ + public $type = 'SimpleCategories'; + + protected function getInput() + { + $size = (int) $this->get('size'); + $attr = $this->get('onchange') ? ' onchange="' . $this->get('onchange') . '"' : ''; + + $categories = $this->getOptions(); + $options = parent::getOptions(); + + if ($this->get('show_none', 1)) + { + $options[] = JHtml::_('select.option', '', '- ' . JText::_('JNONE') . ' -'); + } + + if ($this->get('show_new', 1)) + { + $options[] = JHtml::_('select.option', '-1', '- ' . JText::_('RL_NEW_CATEGORY') . ' -'); + } + + $options = array_merge($options, $categories); + + if ( ! $this->get('show_new', 1)) + { + return JHtml::_('select.genericlist', + $options, + $this->name, + trim($attr), + 'value', + 'text', + $this->value, + $this->id + ); + } + + JHtml::_('jquery.framework'); + RL_Document::script('regularlabs/simplecategories.min.js'); + + $selectlist = $this->selectListSimple( + $options, + $this->getName($this->fieldname . '_select'), + $this->value, + $this->getId('', $this->fieldname . '_select'), + $size, + false + ); + + $html = []; + + $html[] = '
'; + + $html[] = '
' . $selectlist . '
'; + + $html[] = RL_ShowOn::show( + '
' + . '' + . '
', + $this->fieldname . '_select:-1', $this->formControl + ); + + $html[] = ''; + + $html[] = '
'; + + return implode('', $html); + } + + protected function getOptions() + { + $table = $this->get('table'); + + if ( ! $table) + { + return []; + } + + // Get the user groups from the database. + $query = $this->db->getQuery(true) + ->select([ + $this->db->quoteName('category', 'value'), + $this->db->quoteName('category', 'text'), + ]) + ->from($this->db->quoteName('#__' . $table)) + ->where($this->db->quoteName('category') . ' != ' . $this->db->quote('')) + ->group($this->db->quoteName('category')) + ->order($this->db->quoteName('category') . ' ASC'); + $this->db->setQuery($query); + + return $this->db->loadObjectList(); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/slide.php b/deployed/regularlabs/libraries/regularlabs/fields/slide.php new file mode 100644 index 00000000..ad4c8d91 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/slide.php @@ -0,0 +1,99 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +use RegularLabs\Library\Document as RL_Document; +use RegularLabs\Library\StringHelper as RL_String; + +class JFormFieldRL_Slide extends \RegularLabs\Library\Field +{ + public $type = 'Slide'; + + protected function getLabel() + { + return ''; + } + + protected function getInput() + { + $this->params = $this->element->attributes(); + + RL_Document::stylesheet('regularlabs/style.min.css'); + + $label = RL_String::html_entity_decoder(JText::_($this->get('label'))); + $description = $this->prepareText($this->get('description')); + $lang_file = $this->get('language_file'); + + $html = '
'; + $html .= '

'; + $html .= $label; + $html .= '

'; + $html .= '
'; + + if ($lang_file) + { + jimport('joomla.filesystem.file'); + + // Include extra language file + $lang = str_replace('_', '-', JFactory::getLanguage()->getTag()); + + $inc = ''; + $lang_path = 'language/' . $lang . '/' . $lang . '.' . $lang_file . '.inc.php'; + if (JFile::exists(JPATH_ADMINISTRATOR . '/' . $lang_path)) + { + $inc = JPATH_ADMINISTRATOR . '/' . $lang_path; + } + else if (JFile::exists(JPATH_SITE . '/' . $lang_path)) + { + $inc = JPATH_SITE . '/' . $lang_path; + } + if ( ! $inc && $lang != 'en-GB') + { + $lang = 'en-GB'; + $lang_path = 'language/' . $lang . '/' . $lang . '.' . $lang_file . '.inc.php'; + if (JFile::exists(JPATH_ADMINISTRATOR . '/' . $lang_path)) + { + $inc = JPATH_ADMINISTRATOR . '/' . $lang_path; + } + else if (JFile::exists(JPATH_SITE . '/' . $lang_path)) + { + $inc = JPATH_SITE . '/' . $lang_path; + } + } + if ($inc) + { + include $inc; + } + } + + if ($description) + { + if ($description[0] != '<') + { + $description = '

' . $description . '

'; + } + $class = 'rl_panel rl_panel_description'; + $html .= '
'; + $html .= $description; + $html .= '
'; + } + + return $html; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/tags.php b/deployed/regularlabs/libraries/regularlabs/fields/tags.php new file mode 100644 index 00000000..ece0371e --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/tags.php @@ -0,0 +1,97 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\HTML\HTMLHelper as JHtml; +use Joomla\CMS\Language\Text as JText; +use Joomla\Registry\Registry; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_Tags extends \RegularLabs\Library\Field +{ + public $type = 'Tags'; + + protected function getInput() + { + $size = (int) $this->get('size'); + $simple = (int) $this->get('simple'); + $show_ignore = $this->get('show_ignore'); + $use_names = $this->get('use_names'); + + if ($show_ignore && in_array('-1', $this->value)) + { + $this->value = ['-1']; + } + + return $this->selectListAjax( + $this->type, $this->name, $this->value, $this->id, + compact('size', 'simple', 'show_ignore', 'use_names'), + $simple + ); + } + + function getAjaxRaw(Registry $attributes) + { + $name = $attributes->get('name', $this->type); + $id = $attributes->get('id', strtolower($name)); + $value = $attributes->get('value', []); + $size = $attributes->get('size'); + $simple = $attributes->get('simple'); + + $options = $this->getOptions( + (bool) $attributes->get('show_all'), + (bool) $attributes->get('use_names') + ); + + return $this->selectList($options, $name, $value, $id, $size, true, $simple); + } + + protected function getOptions($show_ignore = false, $use_names = false, $value = []) + { + // assemble items to the array + $options = []; + + if ($show_ignore) + { + $options[] = JHtml::_('select.option', '-1', '- ' . JText::_('RL_IGNORE') . ' -'); + $options[] = JHtml::_('select.option', '-', ' ', 'value', 'text', true); + } + + $options = array_merge($options, $this->getTags($use_names)); + + return $options; + } + + protected function getTags($use_names) + { + $value = $use_names ? 'a.title' : 'a.id'; + + $query = $this->db->getQuery(true) + ->select($value . ' as value, a.title as text, a.parent_id AS parent') + ->from('#__tags AS a') + ->select('COUNT(DISTINCT b.id) - 1 AS level') + ->join('LEFT', '#__tags AS b ON a.lft > b.lft AND a.rgt < b.rgt') + ->where('a.alias <> ' . $this->db->quote('root')) + ->where('a.published IN (0,1)') + ->group('a.id') + ->order('a.lft ASC'); + $this->db->setQuery($query); + + return $this->db->loadObjectList(); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/templates.php b/deployed/regularlabs/libraries/regularlabs/fields/templates.php new file mode 100644 index 00000000..aa93758f --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/templates.php @@ -0,0 +1,129 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; +use Joomla\CMS\HTML\HTMLHelper as JHtml; +use Joomla\CMS\Language\Text as JText; +use Joomla\Registry\Registry; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_Templates extends \RegularLabs\Library\Field +{ + public $type = 'Templates'; + + protected function getInput() + { + // fix old '::' separator and change it to '--' + $value = json_encode($this->value); + $value = str_replace('::', '--', $value); + $value = (array) json_decode($value, true); + + $size = (int) $this->get('size'); + $multiple = $this->get('multiple'); + + return $this->selectListAjax( + $this->type, $this->name, $value, $this->id, + compact('size', 'multiple') + ); + } + + function getAjaxRaw(Registry $attributes) + { + $name = $attributes->get('name', $this->type); + $id = $attributes->get('id', strtolower($name)); + $value = $attributes->get('value', []); + $size = $attributes->get('size'); + $multiple = $attributes->get('multiple'); + + $options = $this->getOptions(); + + return $this->selectList($options, $name, $value, $id, $size, $multiple); + } + + protected function getOptions() + { + $options = []; + + $templates = $this->getTemplates(); + + foreach ($templates as $styles) + { + $level = 0; + foreach ($styles as $style) + { + $style->level = $level; + $options[] = $style; + + if (count($styles) <= 2) + { + break; + } + + $level = 1; + } + } + + return $options; + } + + protected function getTemplates() + { + $groups = []; + $lang = JFactory::getLanguage(); + + // Get the database object and a new query object. + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('s.id, s.title, e.name as name, s.template') + ->from('#__template_styles as s') + ->where('s.client_id = 0') + ->join('LEFT', '#__extensions as e on e.element=s.template') + ->where('e.enabled=1') + ->where($db->quoteName('e.type') . '=' . $db->quote('template')) + ->order('s.template') + ->order('s.title'); + + // Set the query and load the styles. + $db->setQuery($query); + $styles = $db->loadObjectList(); + + // Build the grouped list array. + if ($styles) + { + foreach ($styles as $style) + { + $template = $style->template; + $lang->load('tpl_' . $template . '.sys', JPATH_SITE) + || $lang->load('tpl_' . $template . '.sys', JPATH_SITE . '/templates/' . $template); + $name = JText::_($style->name); + + // Initialize the group if necessary. + if ( ! isset($groups[$template])) + { + $groups[$template] = []; + $groups[$template][] = JHtml::_('select.option', $template, $name); + } + + $groups[$template][] = JHtml::_('select.option', $template . '--' . $style->id, $style->title); + } + } + + return $groups; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/text.php b/deployed/regularlabs/libraries/regularlabs/fields/text.php new file mode 100644 index 00000000..cf5797dd --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/text.php @@ -0,0 +1,75 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Language\Text as JText; +use RegularLabs\Library\StringHelper as RL_String; + +require_once JPATH_LIBRARIES . '/joomla/form/fields/text.php'; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_Text extends JFormFieldText +{ + public $type = 'Text'; + + public function setup(SimpleXMLElement $element, $value, $group = null) + { + $this->element = $element; + + $element['label'] = $this->prepareText($element['label']); + $element['description'] = $this->prepareText($element['description']); + $element['hint'] = $this->prepareText($element['hint']); + $element['translateDescription'] = false; + + return parent::setup($element, $value, $group); + } + + private function prepareText($string = '') + { + $string = trim($string); + + if ($string == '') + { + return ''; + } + + // variables + $var1 = JText::_($this->get('var1')); + $var2 = JText::_($this->get('var2')); + $var3 = JText::_($this->get('var3')); + $var4 = JText::_($this->get('var4')); + $var5 = JText::_($this->get('var5')); + + $string = JText::sprintf(JText::_($string), $var1, $var2, $var3, $var4, $var5); + $string = trim(RL_String::html_entity_decoder($string)); + $string = str_replace('"', '"', $string); + $string = str_replace('span style="font-family:monospace;"', 'span class="rl_code"', $string); + + return $string; + } + + private function get($val, $default = '') + { + if ( ! isset($this->params[$val]) || (string) $this->params[$val] == '') + { + return $default; + } + + return (string) $this->params[$val]; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/textareaplus.php b/deployed/regularlabs/libraries/regularlabs/fields/textareaplus.php new file mode 100644 index 00000000..557db6d2 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/textareaplus.php @@ -0,0 +1,114 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Date\Date as JDate; +use Joomla\CMS\Factory as JFactory; +use Joomla\CMS\Language\Text as JText; +use RegularLabs\Library\StringHelper as RL_String; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_TextAreaPlus extends \RegularLabs\Library\Field +{ + public $type = 'TextAreaPlus'; + + protected function getLabel() + { + $resize = $this->get('resize', 0); + $show_insert_date_name = $this->get('show_insert_date_name', 0); + + $label = RL_String::html_entity_decoder(JText::_($this->get('label'))); + + $attribs = 'id="' . $this->id . '-lbl" for="' . $this->id . '"'; + + if ($this->description) + { + $attribs .= ' class="hasPopover" title="' . $label . '"' + . ' data-content="' . JText::_($this->description) . '"'; + } + + $html = ''; + + return $html; + } + + protected function getInput() + { + $width = $this->get('width', 600); + $height = $this->get('height', 80); + $class = ' class="' . trim('rl_textarea ' . $this->get('class')) . '"'; + $type = $this->get('texttype'); + $hint = $this->get('hint'); + + if (is_array($this->value)) + { + $this->value = trim(implode("\n", $this->value)); + } + + if ($type == 'html') + { + // Convert
tags so they are not visible when editing + $this->value = str_replace('
', "\n", $this->value); + } + else if ($type == 'regex') + { + // Protects the special characters + $this->value = str_replace('[:REGEX_ENTER:]', '\n', $this->value); + } + + if ($this->get('translate') && $this->get('translate') !== 'false') + { + $this->value = JText::_($this->value); + $hint = JText::_($hint); + } + + $this->value = htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8'); + + $hint = $hint ? ' placeholder="' . $hint . '"' : ''; + + return + ''; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/toggler.php b/deployed/regularlabs/libraries/regularlabs/fields/toggler.php new file mode 100644 index 00000000..2c113420 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/toggler.php @@ -0,0 +1,144 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; +use Joomla\CMS\Form\FormField as JFormField; +use RegularLabs\Library\Document as RL_Document; +use RegularLabs\Library\RegEx as RL_RegEx; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +/** + * @deprecated 2018-10-30 Use ShowOn instead + */ + +/** + * To use this, make a start xml param tag with the param and value set + * And an end xml param tag without the param and value set + * Everything between those tags will be included in the slide + * + * Available extra parameters: + * param The name of the reference parameter + * value a comma separated list of value on which to show the framework + */ +class JFormFieldRL_Toggler extends JFormField +{ + public $type = 'Toggler'; + + protected function getLabel() + { + return ''; + } + + protected function getInput() + { + if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) + { + return null; + } + + $field = new RLFieldToggler; + + return $field->getInput($this->element->attributes()); + } +} + +class RLFieldToggler +{ + function getInput($params) + { + $this->params = $params; + + $option = JFactory::getApplication()->input->get('option'); + + // do not place toggler stuff on JoomFish pages + if ($option == 'com_joomfish') + { + return ''; + } + + $param = $this->get('param'); + $value = $this->get('value'); + $nofx = $this->get('nofx'); + $method = $this->get('method'); + $div = $this->get('div', 0); + + RL_Document::script('regularlabs/toggler.min.js'); + + $param = RL_RegEx::replace('^\s*(.*?)\s*$', '\1', $param); + $param = RL_RegEx::replace('\s*\|\s*', '|', $param); + + $html = []; + if ( ! $param) + { + return ''; + } + + $param = RL_RegEx::replace('[^a-z0-9-\.\|\@]', '_', $param); + $param = str_replace('@', '_', $param); + $set_groups = explode('|', $param); + $set_values = explode('|', $value); + $ids = []; + foreach ($set_groups as $i => $group) + { + $count = $i; + if ($count >= count($set_values)) + { + $count = 0; + } + $value = explode(',', $set_values[$count]); + foreach ($value as $val) + { + $ids[] = $group . '.' . $val; + } + } + + if ( ! $div) + { + $html[] = ''; + } + + $html[] = '
'; + + if ( ! $div) + { + $html[] = '
'; + } + + return implode('', $html); + } + + private function get($val, $default = '') + { + if ( ! isset($this->params[$val]) || (string) $this->params[$val] == '') + { + return $default; + } + + return (string) $this->params[$val]; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/users.php b/deployed/regularlabs/libraries/regularlabs/fields/users.php new file mode 100644 index 00000000..69b88fa9 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/users.php @@ -0,0 +1,87 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Language\Text as JText; +use Joomla\Registry\Registry; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_Users extends \RegularLabs\Library\Field +{ + public $type = 'Users'; + + protected function getInput() + { + if ( ! is_array($this->value)) + { + $this->value = explode(',', $this->value); + } + + $size = (int) $this->get('size'); + $multiple = $this->get('multiple'); + + return $this->selectListSimpleAjax( + $this->type, $this->name, $this->value, $this->id, + compact('size', 'multiple') + ); + } + + function getAjaxRaw(Registry $attributes) + { + $name = $attributes->get('name', $this->type); + $id = $attributes->get('id', strtolower($name)); + $value = $attributes->get('value', []); + $size = $attributes->get('size'); + $multiple = $attributes->get('multiple'); + + $options = $this->getUsers(); + + return $this->selectListSimple($options, $name, $value, $id, $size, $multiple); + } + + function getUsers() + { + $query = $this->db->getQuery(true) + ->select('COUNT(*)') + ->from('#__users AS u'); + $this->db->setQuery($query); + $total = $this->db->loadResult(); + + if ($total > $this->max_list_count) + { + return -1; + } + + $query->clear('select') + ->select('u.name, u.username, u.id, u.block as disabled') + ->order('name'); + $this->db->setQuery($query); + $list = $this->db->loadObjectList(); + + $list = array_map(function ($item) { + if ($item->disabled) + { + $item->name .= ' (' . JText::_('JDISABLED') . ')'; + } + + return $item; + }, $list); + + return $this->getOptionsByList($list, ['username', 'id']); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/version.php b/deployed/regularlabs/libraries/regularlabs/fields/version.php new file mode 100644 index 00000000..0a304e8b --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/version.php @@ -0,0 +1,67 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; +use RegularLabs\Library\Version as RL_Version; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_Version extends \RegularLabs\Library\Field +{ + public $type = 'Version'; + + protected function getLabel() + { + return ''; + } + + protected function getInput() + { + $extension = $this->get('extension'); + $xml = $this->get('xml'); + + if ( ! $xml && $this->form->getValue('element')) + { + if ($this->form->getValue('folder')) + { + $xml = 'plugins/' . $this->form->getValue('folder') . '/' . $this->form->getValue('element') . '/' . $this->form->getValue('element') . '.xml'; + } + else + { + $xml = 'administrator/modules/' . $this->form->getValue('element') . '/' . $this->form->getValue('element') . '.xml'; + } + if ( ! JFile::exists(JPATH_SITE . '/' . $xml)) + { + return ''; + } + } + + if ( ! strlen($extension) || ! strlen($xml)) + { + return ''; + } + + $authorise = JFactory::getUser()->authorise('core.manage', 'com_installer'); + if ( ! $authorise) + { + return ''; + } + + return '
' . RL_Version::getMessage($extension); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/virtuemart.php b/deployed/regularlabs/libraries/regularlabs/fields/virtuemart.php new file mode 100644 index 00000000..54d45e3f --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/virtuemart.php @@ -0,0 +1,131 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_VirtueMart extends \RegularLabs\Library\FieldGroup +{ + public $type = 'VirtueMart'; + public $language = null; + + protected function getInput() + { + if ($error = $this->missingFilesOrTables(['categories', 'products'])) + { + return $error; + } + + return $this->getSelectList(); + } + + function getCategories() + { + $query = $this->db->getQuery(true) + ->select('COUNT(*)') + ->from('#__virtuemart_categories AS c') + ->where('c.published > -1'); + $this->db->setQuery($query); + $total = $this->db->loadResult(); + + if ($total > $this->max_list_count) + { + return -1; + } + + $query->clear() + ->select('c.virtuemart_category_id as id, cc.category_parent_id AS parent_id, l.category_name AS title, c.published') + ->from('#__virtuemart_categories_' . $this->getActiveLanguage() . ' AS l') + ->join('', '#__virtuemart_categories AS c using (virtuemart_category_id)') + ->join('LEFT', '#__virtuemart_category_categories AS cc ON l.virtuemart_category_id = cc.category_child_id') + ->where('c.published > -1') + ->group('c.virtuemart_category_id') + ->order('c.ordering, l.category_name'); + $this->db->setQuery($query); + $items = $this->db->loadObjectList(); + + return $this->getOptionsTreeByList($items); + } + + function getProducts() + { + $query = $this->db->getQuery(true) + ->select('COUNT(*)') + ->from('#__virtuemart_products AS p') + ->where('p.published > -1'); + $this->db->setQuery($query); + $total = $this->db->loadResult(); + + if ($total > $this->max_list_count) + { + return -1; + } + + $query->clear('select') + ->select('p.virtuemart_product_id as id, l.product_name AS name, p.product_sku as sku, cl.category_name AS cat, p.published') + ->join('LEFT', '#__virtuemart_products_' . $this->getActiveLanguage() . ' AS l ON l.virtuemart_product_id = p.virtuemart_product_id') + ->join('LEFT', '#__virtuemart_product_categories AS x ON x.virtuemart_product_id = p.virtuemart_product_id') + ->join('LEFT', '#__virtuemart_categories AS c ON c.virtuemart_category_id = x.virtuemart_category_id') + ->join('LEFT', '#__virtuemart_categories_' . $this->getActiveLanguage() . ' AS cl ON cl.virtuemart_category_id = c.virtuemart_category_id') + ->group('p.virtuemart_product_id') + ->order('l.product_name, p.product_sku'); + $this->db->setQuery($query); + $list = $this->db->loadObjectList(); + + return $this->getOptionsByList($list, ['sku', 'cat', 'id']); + } + + private function getActiveLanguage() + { + if (isset($this->language)) + { + return $this->language; + } + + $this->language = 'en_gb'; + + if ( ! class_exists('VmConfig')) + { + require_once JPATH_ROOT . '/administrator/components/com_virtuemart/helpers/config.php'; + } + + if ( ! class_exists('VmConfig')) + { + return $this->language; + } + + VmConfig::loadConfig(); + + if ( ! empty(VmConfig::$vmlang)) + { + $this->language = str_replace('-', '_', strtolower(VmConfig::$vmlang)); + + return $this->language; + } + + $active_languages = VmConfig::get('active_languages', []); + + if ( ! isset($active_languages[0])) + { + return $this->language; + } + + $this->language = str_replace('-', '_', strtolower($active_languages[0])); + + return $this->language; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/fields/zoo.php b/deployed/regularlabs/libraries/regularlabs/fields/zoo.php new file mode 100644 index 00000000..b0d7e555 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/fields/zoo.php @@ -0,0 +1,145 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\HTML\HTMLHelper as JHtml; +use Joomla\CMS\Language\Text as JText; +use RegularLabs\Library\Form as RL_Form; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +class JFormFieldRL_Zoo extends \RegularLabs\Library\FieldGroup +{ + public $type = 'Zoo'; + + protected function getInput() + { + if ($error = $this->missingFilesOrTables(['applications' => 'application', 'categories' => 'category', 'items' => 'item'])) + { + return $error; + } + + return $this->getSelectList(); + } + + function getCategories() + { + $query = $this->db->getQuery(true) + ->select('COUNT(*)') + ->from('#__zoo_category AS c') + ->where('c.published > -1'); + $this->db->setQuery($query); + $total = $this->db->loadResult(); + + if ($total > $this->max_list_count) + { + return -1; + } + + $options = []; + if ($this->get('show_ignore')) + { + if (in_array('-1', $this->value)) + { + $this->value = ['-1']; + } + $options[] = JHtml::_('select.option', '-1', '- ' . JText::_('RL_IGNORE') . ' -'); + $options[] = JHtml::_('select.option', '-', ' ', 'value', 'text', true); + } + + $query->clear() + ->select('a.id, a.name') + ->from('#__zoo_application AS a') + ->order('a.name, a.id'); + $this->db->setQuery($query); + $apps = $this->db->loadObjectList(); + + foreach ($apps as $i => $app) + { + $query->clear() + ->select('c.id, c.parent AS parent_id, c.name AS title, c.published') + ->from('#__zoo_category AS c') + ->where('c.application_id = ' . (int) $app->id) + ->where('c.published > -1') + ->order('c.ordering, c.name'); + $this->db->setQuery($query); + $items = $this->db->loadObjectList(); + + if ($i) + { + $options[] = JHtml::_('select.option', '-', ' ', 'value', 'text', true); + } + + // establish the hierarchy of the menu + // TODO: use node model + $children = []; + + if ($items) + { + // first pass - collect children + foreach ($items as $v) + { + $pt = $v->parent_id; + $list = @$children[$pt] ? $children[$pt] : []; + array_push($list, $v); + $children[$pt] = $list; + } + } + + // second pass - get an indent list of the items + $list = JHtml::_('menu.treerecurse', 0, '', [], $children, 9999, 0, 0); + + // assemble items to the array + $options[] = JHtml::_('select.option', 'app' . $app->id, '[' . $app->name . ']'); + foreach ($list as $item) + { + $item->treename = ' ' . str_replace('  - ', ' ', $item->treename); + $item->treename = RL_Form::prepareSelectItem($item->treename, $item->published); + $option = JHtml::_('select.option', $item->id, $item->treename); + $option->level = 1; + $options[] = $option; + } + } + + return $options; + } + + function getItems() + { + $query = $this->db->getQuery(true) + ->select('COUNT(*)') + ->from('#__zoo_item AS i') + ->where('i.state > -1'); + $this->db->setQuery($query); + $total = $this->db->loadResult(); + + if ($total > $this->max_list_count) + { + return -1; + } + + $query->clear('select') + ->select('i.id, i.name, a.name as cat, i.state as published') + ->join('LEFT', '#__zoo_application AS a ON a.id = i.application_id') + ->group('i.id') + ->order('i.name, i.priority, i.id'); + $this->db->setQuery($query); + $list = $this->db->loadObjectList(); + + return $this->getOptionsByList($list, ['cat', 'id']); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignment.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignment.php new file mode 100644 index 00000000..d88b1fbd --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignment.php @@ -0,0 +1,53 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +class RLAssignment + extends \RegularLabs\Library\Condition +{ + function pass($pass = true, $include_type = null) + { + return $this->_($pass, $include_type); + } + + public function passByPageTypes($option, $selection = [], $assignment = 'all', $add_view = false, $get_task = false, $get_layout = true) + { + return $this->passByPageType($option, $selection, $assignment, $add_view, $get_task, $get_layout); + } + + public function passContentIds() + { + return $this->passContentId(); + } + + public function passContentKeywords($fields = ['title', 'introtext', 'fulltext'], $text = '') + { + return $this->passContentKeyword($fields, $text); + } + + public function passMetaKeywords($field = 'metakey', $keywords = '') + { + return $this->passMetaKeyword($field, $keywords); + } + + public function passAuthors($field = 'created_by', $author = '') + { + return $this->passAuthors($field, $author); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments.php new file mode 100644 index 00000000..66a3a678 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments.php @@ -0,0 +1,44 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use RegularLabs\Library\Conditions as RL_Conditions; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +class RLAssignmentsHelper +{ + function passAll($assignments, $matching_method = 'all', $item = 0) + { + return RL_Conditions::pass($assignments, $matching_method, $item); + } + + public function getAssignmentsFromParams(&$params) + { + return RL_Conditions::getConditionsFromParams($params); + } + + public function getAssignmentsFromTagAttributes(&$params, $types = []) + { + return RL_Conditions::getConditionsFromTagAttributes($params, $types); + } + + public function hasAssignments(&$assignments) + { + return RL_Conditions::hasConditions($assignments); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments/agents.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/agents.php new file mode 100644 index 00000000..0c6e9eb7 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/agents.php @@ -0,0 +1,199 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +require_once dirname(__DIR__) . '/assignment.php'; +require_once dirname(__DIR__) . '/text.php'; +require_once dirname(__DIR__) . '/mobile_detect.php'; + +class RLAssignmentsAgents extends RLAssignment +{ + var $agent = null; + var $device = null; + + /** + * passBrowsers + */ + public function passBrowsers() + { + if (empty($this->selection)) + { + return $this->pass(false); + } + + foreach ($this->selection as $browser) + { + if ( ! $this->passBrowser($browser)) + { + continue; + } + + return $this->pass(true); + } + + return $this->pass(false); + } + + /** + * passOS + */ + public function passOS() + { + return self::passBrowsers(); + } + + /** + * passDevices + */ + public function passDevices() + { + $pass = (in_array('mobile', $this->selection) && $this->isMobile()) + || (in_array('tablet', $this->selection) && $this->isTablet()) + || (in_array('desktop', $this->selection) && $this->isDesktop()); + + return $this->pass($pass); + } + + /** + * isPhone + */ + public function isPhone() + { + return $this->isMobile(); + } + + /** + * isMobile + */ + public function isMobile() + { + return $this->getDevice() == 'mobile'; + } + + /** + * isTablet + */ + public function isTablet() + { + return $this->getDevice() == 'tablet'; + } + + /** + * isDesktop + */ + public function isDesktop() + { + return $this->getDevice() == 'desktop'; + } + + /** + * setDevice + */ + private function getDevice() + { + if ( ! is_null($this->device)) + { + return $this->device; + } + + $detect = new RLMobile_Detect; + + $this->is_mobile = $detect->isMobile(); + + switch (true) + { + case($detect->isTablet()): + $this->device = 'tablet'; + break; + + case ($detect->isMobile()): + $this->device = 'mobile'; + break; + + default: + $this->device = 'desktop'; + } + + return $this->device; + } + + /** + * getAgent + */ + private function getAgent() + { + if ( ! is_null($this->agent)) + { + return $this->agent; + } + + $detect = new RLMobile_Detect; + $agent = $detect->getUserAgent(); + + switch (true) + { + case (stripos($agent, 'Trident') !== false): + // Add MSIE to IE11 + $agent = preg_replace('#(Trident/[0-9\.]+; rv:([0-9\.]+))#is', '\1 MSIE \2', $agent); + break; + + case (stripos($agent, 'Chrome') !== false): + // Remove Safari from Chrome + $agent = preg_replace('#(Chrome/.*)Safari/[0-9\.]*#is', '\1', $agent); + // Add MSIE to IE Edge and remove Chrome from IE Edge + $agent = preg_replace('#Chrome/.*(Edge/[0-9])#is', 'MSIE \1', $agent); + break; + + case (stripos($agent, 'Opera') !== false): + $agent = preg_replace('#(Opera/.*)Version/#is', '\1Opera/', $agent); + break; + } + + $this->agent = $agent; + + return $this->agent; + } + + /** + * passBrowser + */ + private function passBrowser($browser = '') + { + if ( ! $browser) + { + return false; + } + + if ($browser == 'mobile') + { + return $this->isMobile(); + } + + if ( ! (strpos($browser, '#') === 0)) + { + $browser = '#' . RLText::pregQuote($browser) . '#'; + } + + // also check for _ instead of . + $browser = preg_replace('#\\\.([^\]])#', '[\._]\1', $browser); + $browser = str_replace('\.]', '\._]', $browser); + + return preg_match($browser . 'i', $this->getAgent()); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments/akeebasubs.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/akeebasubs.php new file mode 100644 index 00000000..e3e3902b --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/akeebasubs.php @@ -0,0 +1,56 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +class RLAssignmentsAkeebaSubs extends RLAssignment +{ + public function init() + { + if ( ! $this->request->id && $this->request->view == 'level') + { + $slug = JFactory::getApplication()->input->getString('slug', ''); + if ($slug) + { + $query = $this->db->getQuery(true) + ->select('l.akeebasubs_level_id') + ->from('#__akeebasubs_levels AS l') + ->where('l.slug = ' . $this->db->quote($slug)); + $this->db->setQuery($query); + $this->request->id = $this->db->loadResult(); + } + } + } + + public function passPageTypes() + { + return $this->passByPageTypes('com_akeebasubs', $this->selection, $this->assignment); + } + + public function passLevels() + { + if ( ! $this->request->id || $this->request->option != 'com_akeebasubs' || $this->request->view != 'level') + { + return $this->pass(false); + } + + return $this->passSimple($this->request->id); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments/components.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/components.php new file mode 100644 index 00000000..f0d09e87 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/components.php @@ -0,0 +1,29 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +require_once dirname(__DIR__) . '/assignment.php'; + +class RLAssignmentsComponents extends RLAssignment +{ + public function passComponents() + { + return $this->passSimple(strtolower($this->request->option)); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments/content.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/content.php new file mode 100644 index 00000000..34fc9e20 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/content.php @@ -0,0 +1,245 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; +use Joomla\CMS\MVC\Model\BaseDatabaseModel as JModel; +use Joomla\CMS\Table\Table as JTable; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +require_once dirname(__DIR__) . '/assignment.php'; + +class RLAssignmentsContent extends RLAssignment +{ + public function passPageTypes() + { + $components = ['com_content', 'com_contentsubmit']; + if ( ! in_array($this->request->option, $components)) + { + return $this->pass(false); + } + if ($this->request->view == 'category' && $this->request->layout == 'blog') + { + $view = 'categoryblog'; + } + else + { + $view = $this->request->view; + } + + return $this->passSimple($view); + } + + public function passCategories() + { + // components that use the com_content secs/cats + $components = ['com_content', 'com_flexicontent', 'com_contentsubmit']; + if ( ! in_array($this->request->option, $components)) + { + return $this->pass(false); + } + + if (empty($this->selection)) + { + return $this->pass(false); + } + + $is_content = in_array($this->request->option, ['com_content', 'com_flexicontent']); + $is_category = in_array($this->request->view, ['category']); + $is_item = in_array($this->request->view, ['', 'article', 'item', 'form']); + + if ( + $this->request->option != 'com_contentsubmit' + && ! ($this->params->inc_categories && $is_content && $is_category) + && ! ($this->params->inc_articles && $is_content && $is_item) + && ! ($this->params->inc_others && ! ($is_content && ($is_category || $is_item))) + ) + { + return $this->pass(false); + } + + if ($this->request->option == 'com_contentsubmit') + { + // Content Submit + $contentsubmit_params = new ContentsubmitModelArticle; + if (in_array($contentsubmit_params->_id, $this->selection)) + { + return $this->pass(true); + } + + return $this->pass(false); + } + + $pass = false; + if ( + $this->params->inc_others + && ! ($is_content && ($is_category || $is_item)) + && $this->article + ) + { + if ( ! isset($this->article->id) && isset($this->article->slug)) + { + $this->article->id = (int) $this->article->slug; + } + + if ( ! isset($this->article->catid) && isset($this->article->catslug)) + { + $this->article->catid = (int) $this->article->catslug; + } + + $this->request->id = $this->article->id; + $this->request->view = 'article'; + } + + $catids = $this->getCategoryIds($is_category); + + foreach ($catids as $catid) + { + if ( ! $catid) + { + continue; + } + + $pass = in_array($catid, $this->selection); + + if ($pass && $this->params->inc_children == 2) + { + $pass = false; + continue; + } + + if ( ! $pass && $this->params->inc_children) + { + $parent_ids = $this->getCatParentIds($catid); + $parent_ids = array_diff($parent_ids, [1]); + foreach ($parent_ids as $id) + { + if (in_array($id, $this->selection)) + { + $pass = true; + break; + } + } + + unset($parent_ids); + } + } + + return $this->pass($pass); + } + + private function getCategoryIds($is_category = false) + { + if ($is_category) + { + return (array) $this->request->id; + } + + if ( ! $this->article && $this->request->id) + { + $this->article = JTable::getInstance('content'); + $this->article->load($this->request->id); + } + + if ($this->article && $this->article->catid) + { + return (array) $this->article->catid; + } + + $catid = JFactory::getApplication()->input->getInt('catid', JFactory::getApplication()->getUserState('com_content.articles.filter.category_id')); + $menuparams = $this->getMenuItemParams($this->request->Itemid); + + if ($this->request->view == 'featured') + { + $menuparams = $this->getMenuItemParams($this->request->Itemid); + + return isset($menuparams->featured_categories) ? (array) $menuparams->featured_categories : (array) $catid; + } + + return isset($menuparams->catid) ? (array) $menuparams->catid : (array) $catid; + } + + public function passArticles() + { + if ( ! $this->request->id + || ! (($this->request->option == 'com_content' && $this->request->view == 'article') + || ($this->request->option == 'com_flexicontent' && $this->request->view == 'item') + ) + ) + { + return $this->pass(false); + } + + $pass = false; + + // Pass Article Id + if ( ! $this->passItemByType($pass, 'ContentIds')) + { + return $this->pass(false); + } + + // Pass Content Keywords + if ( ! $this->passItemByType($pass, 'ContentKeywords')) + { + return $this->pass(false); + } + + // Pass Meta Keywords + if ( ! $this->passItemByType($pass, 'MetaKeywords')) + { + return $this->pass(false); + } + + // Pass Authors + if ( ! $this->passItemByType($pass, 'Authors')) + { + return $this->pass(false); + } + + return $this->pass($pass); + } + + public function getItem($fields = []) + { + if ($this->article) + { + return $this->article; + } + + if ( ! class_exists('ContentModelArticle')) + { + require_once JPATH_SITE . '/components/com_content/models/article.php'; + } + + $model = JModel::getInstance('article', 'contentModel'); + + if ( ! method_exists($model, 'getItem')) + { + return null; + } + + $this->article = $model->getItem($this->request->id); + + return $this->article; + } + + private function getCatParentIds($id = 0) + { + return $this->getParentIds($id, 'categories'); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments/cookieconfirm.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/cookieconfirm.php new file mode 100644 index 00000000..cd592730 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/cookieconfirm.php @@ -0,0 +1,32 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +require_once dirname(__DIR__) . '/assignment.php'; + +class RLAssignmentsCookieConfirm extends RLAssignment +{ + public function passCookieConfirm() + { + require_once JPATH_PLUGINS . '/system/cookieconfirm/core.php'; + $pass = PlgSystemCookieconfirmCore::getInstance()->isCookiesAllowed(); + + return $this->pass($pass); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments/datetime.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/datetime.php new file mode 100644 index 00000000..882bf746 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/datetime.php @@ -0,0 +1,278 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +require_once dirname(__DIR__) . '/assignment.php'; + +class RLAssignmentsDateTime extends RLAssignment +{ + var $timezone = null; + var $dates = []; + + public function passDate() + { + if ( ! $this->params->publish_up && ! $this->params->publish_down) + { + // no date range set + return ($this->assignment == 'include'); + } + + require_once dirname(__DIR__) . '/text.php'; + + RLText::fixDate($this->params->publish_up); + RLText::fixDate($this->params->publish_down); + + $now = $this->getNow(); + $up = $this->getDate($this->params->publish_up); + $down = $this->getDate($this->params->publish_down); + + if (isset($this->params->recurring) && $this->params->recurring) + { + if ( ! (int) $this->params->publish_up || ! (int) $this->params->publish_down) + { + // no date range set + return ($this->assignment == 'include'); + } + + $up = strtotime(date('Y') . $up->format('-m-d H:i:s', true)); + $down = strtotime(date('Y') . $down->format('-m-d H:i:s', true)); + + // pass: + // 1) now is between up and down + // 2) up is later in year than down and: + // 2a) now is after up + // 2b) now is before down + if ( + ($up < $now && $down > $now) + || ($up > $down + && ( + $up < $now + || $down > $now + ) + ) + ) + { + return ($this->assignment == 'include'); + } + + // outside date range + return $this->pass(false); + } + + if ( + ( + (int) $this->params->publish_up + && strtotime($up->format('Y-m-d H:i:s', true)) > $now + ) + || ( + (int) $this->params->publish_down + && strtotime($down->format('Y-m-d H:i:s', true)) < $now + ) + ) + { + // outside date range + return $this->pass(false); + } + + // pass + return ($this->assignment == 'include'); + } + + public function passSeasons() + { + $season = self::getSeason($this->date, $this->params->hemisphere); + + return $this->passSimple($season); + } + + public function passMonths() + { + $month = $this->date->format('m', true); // 01 (for January) through 12 (for December) + + return $this->passSimple((int) $month); + } + + public function passDays() + { + $day = $this->date->format('N', true); // 1 (for Monday) though 7 (for Sunday ) + + return $this->passSimple($day); + } + + public function passTime() + { + $now = $this->getNow(); + $up = strtotime($this->date->format('Y-m-d ', true) . $this->params->publish_up); + $down = strtotime($this->date->format('Y-m-d ', true) . $this->params->publish_down); + + if ($up > $down) + { + // publish up is after publish down (spans midnight) + // current time should be: + // - after publish up + // - OR before publish down + if ($now >= $up || $now < $down) + { + return $this->pass(true); + } + + return $this->pass(false); + } + + // publish down is after publish up (simple time span) + // current time should be: + // - after publish up + // - AND before publish down + if ($now >= $up && $now < $down) + { + return $this->pass(true); + } + + return $this->pass(false); + } + + private function getSeason(&$d, $hemisphere = 'northern') + { + // Set $date to today + $date = strtotime($d->format('Y-m-d H:i:s', true)); + + // Get year of date specified + $date_year = $d->format('Y', true); // Four digit representation for the year + + // Specify the season names + $season_names = ['winter', 'spring', 'summer', 'fall']; + + // Declare season date ranges + switch (strtolower($hemisphere)) + { + case 'southern': + if ( + $date < strtotime($date_year . '-03-21') + || $date >= strtotime($date_year . '-12-21') + ) + { + return $season_names[2]; // Must be in Summer + } + + if ($date >= strtotime($date_year . '-09-23')) + { + return $season_names[1]; // Must be in Spring + } + + if ($date >= strtotime($date_year . '-06-21')) + { + return $season_names[0]; // Must be in Winter + } + + if ($date >= strtotime($date_year . '-03-21')) + { + return $season_names[3]; // Must be in Fall + } + break; + case 'australia': + if ( + $date < strtotime($date_year . '-03-01') + || $date >= strtotime($date_year . '-12-01') + ) + { + return $season_names[2]; // Must be in Summer + } + + if ($date >= strtotime($date_year . '-09-01')) + { + return $season_names[1]; // Must be in Spring + } + + if ($date >= strtotime($date_year . '-06-01')) + { + return $season_names[0]; // Must be in Winter + } + + if ($date >= strtotime($date_year . '-03-01')) + { + return $season_names[3]; // Must be in Fall + } + break; + default: // northern + if ( + $date < strtotime($date_year . '-03-21') + || $date >= strtotime($date_year . '-12-21') + ) + { + return $season_names[0]; // Must be in Winter + } + + if ($date >= strtotime($date_year . '-09-23')) + { + return $season_names[3]; // Must be in Fall + } + + if ($date >= strtotime($date_year . '-06-21')) + { + return $season_names[2]; // Must be in Summer + } + + if ($date >= strtotime($date_year . '-03-21')) + { + return $season_names[1]; // Must be in Spring + } + break; + } + + return 0; + } + + private function getNow() + { + return strtotime($this->date->format('Y-m-d H:i:s', true)); + } + + private function getDate($date = '') + { + $id = 'date_' . $date; + + if (isset($this->dates[$id])) + { + return $this->dates[$id]; + } + + $this->dates[$id] = JFactory::getDate($date); + + if (empty($this->params->ignore_time_zone)) + { + $this->dates[$id]->setTimeZone($this->getTimeZone()); + } + + return $this->dates[$id]; + } + + private function getTimeZone() + { + if ( ! is_null($this->timezone)) + { + return $this->timezone; + } + + $this->timezone = new DateTimeZone(JFactory::getApplication()->getCfg('offset')); + + return $this->timezone; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments/easyblog.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/easyblog.php new file mode 100644 index 00000000..858a8ee2 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/easyblog.php @@ -0,0 +1,186 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +require_once dirname(__DIR__) . '/assignment.php'; + +class RLAssignmentsEasyBlog extends RLAssignment +{ + public function passPageTypes() + { + return $this->passByPageTypes('com_easyblog', $this->selection, $this->assignment); + } + + public function passCategories() + { + if ($this->request->option != 'com_easyblog') + { + return $this->pass(false); + } + + $pass = ( + ($this->params->inc_categories && $this->request->view == 'categories') + || ($this->params->inc_items && $this->request->view == 'entry') + ); + + if ( ! $pass) + { + return $this->pass(false); + } + + $cats = $this->makeArray($this->getCategories()); + + $pass = $this->passSimple($cats, 'include'); + + if ($pass && $this->params->inc_children == 2) + { + return $this->pass(false); + } + else if ( ! $pass && $this->params->inc_children) + { + foreach ($cats as $cat) + { + $cats = array_merge($cats, $this->getCatParentIds($cat)); + } + } + + return $this->passSimple($cats); + } + + private function getCategories() + { + switch ($this->request->view) + { + case 'entry' : + return $this->getCategoryIDFromItem(); + break; + + case 'categories' : + return $this->request->id; + break; + + default: + return ''; + } + } + + private function getCategoryIDFromItem() + { + $query = $this->db->getQuery(true) + ->select('i.category_id') + ->from('#__easyblog_post AS i') + ->where('i.id = ' . (int) $this->request->id); + $this->db->setQuery($query); + + return $this->db->loadResult(); + } + + public function passTags() + { + if ($this->request->option != 'com_easyblog') + { + return $this->pass(false); + } + + $pass = ( + ($this->params->inc_tags && $this->request->layout == 'tag') + || ($this->params->inc_items && $this->request->view == 'entry') + ); + + if ( ! $pass) + { + return $this->pass(false); + } + + if ($this->params->inc_tags && $this->request->layout == 'tag') + { + $query = $this->db->getQuery(true) + ->select('t.alias') + ->from('#__easyblog_tag AS t') + ->where('t.id = ' . (int) $this->request->id) + ->where('t.published = 1'); + $this->db->setQuery($query); + $tags = $this->db->loadColumn(); + + return $this->passSimple($tags, true); + } + + $query = $this->db->getQuery(true) + ->select('t.alias') + ->from('#__easyblog_post_tag AS x') + ->join('LEFT', '#__easyblog_tag AS t ON t.id = x.tag_id') + ->where('x.post_id = ' . (int) $this->request->id) + ->where('t.published = 1'); + $this->db->setQuery($query); + $tags = $this->db->loadColumn(); + + return $this->passSimple($tags, true); + } + + public function passItems() + { + if ( ! $this->request->id || $this->request->option != 'com_easyblog' || $this->request->view != 'entry') + { + return $this->pass(false); + } + + $pass = false; + + // Pass Article Id + if ( ! $this->passItemByType($pass, 'ContentIds')) + { + return $this->pass(false); + } + + // Pass Content Keywords + if ( ! $this->passItemByType($pass, 'ContentKeywords')) + { + return $this->pass(false); + } + + // Pass Authors + if ( ! $this->passItemByType($pass, 'Authors')) + { + return $this->pass(false); + } + + return $this->pass($pass); + } + + public function passContentKeywords($fields = ['title', 'intro', 'content'], $text = '') + { + parent::passContentKeywords($fields); + } + + public function getItem($fields = []) + { + $query = $this->db->getQuery(true) + ->select($fields) + ->from('#__easyblog_post') + ->where('id = ' . (int) $this->request->id); + $this->db->setQuery($query); + + return $this->db->loadObject(); + } + + private function getCatParentIds($id = 0) + { + return $this->getParentIds($id, 'easyblog_category', 'parent_id'); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments/flexicontent.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/flexicontent.php new file mode 100644 index 00000000..5d04c55f --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/flexicontent.php @@ -0,0 +1,100 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +require_once dirname(__DIR__) . '/assignment.php'; + +class RLAssignmentsFlexiContent extends RLAssignment +{ + public function passPageTypes() + { + return $this->passByPageTypes('com_flexicontent', $this->selection, $this->assignment); + } + + public function passTags() + { + if ($this->request->option != 'com_flexicontent') + { + return $this->pass(false); + } + + $pass = ( + ($this->params->inc_tags && $this->request->view == 'tags') + || ($this->params->inc_items && in_array($this->request->view, ['item', 'items'])) + ); + + if ( ! $pass) + { + return $this->pass(false); + } + + if ($this->params->inc_tags && $this->request->view == 'tags') + { + $query = $this->db->getQuery(true) + ->select('t.name') + ->from('#__flexicontent_tags AS t') + ->where('t.id = ' . (int) trim(JFactory::getApplication()->input->getInt('id', 0))) + ->where('t.published = 1'); + $this->db->setQuery($query); + $tag = $this->db->loadResult(); + $tags = [$tag]; + } + else + { + $query = $this->db->getQuery(true) + ->select('t.name') + ->from('#__flexicontent_tags_item_relations AS x') + ->join('LEFT', '#__flexicontent_tags AS t ON t.id = x.tid') + ->where('x.itemid = ' . (int) $this->request->id) + ->where('t.published = 1'); + $this->db->setQuery($query); + $tags = $this->db->loadColumn(); + } + + return $this->passSimple($tags, true); + } + + public function passTypes() + { + if ($this->request->option != 'com_flexicontent') + { + return $this->pass(false); + } + + $pass = in_array($this->request->view, ['item', 'items']); + + if ( ! $pass) + { + return $this->pass(false); + } + + $query = $this->db->getQuery(true) + ->select('x.type_id') + ->from('#__flexicontent_items_ext AS x') + ->where('x.item_id = ' . (int) $this->request->id); + $this->db->setQuery($query); + $type = $this->db->loadResult(); + + $types = $this->makeArray($type); + + return $this->passSimple($types); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments/form2content.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/form2content.php new file mode 100644 index 00000000..43942b26 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/form2content.php @@ -0,0 +1,43 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +require_once dirname(__DIR__) . '/assignment.php'; + +class RLAssignmentsForm2Content extends RLAssignment +{ + public function passProjects() + { + if ($this->request->option != 'com_content' && $this->request->view == 'article') + { + return $this->pass(false); + } + + $query = $this->db->getQuery(true) + ->select('c.projectid') + ->from('#__f2c_form AS c') + ->where('c.reference_id = ' . (int) $this->request->id); + $this->db->setQuery($query); + $type = $this->db->loadResult(); + + $types = $this->makeArray($type); + + return $this->passSimple($types); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments/geo.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/geo.php new file mode 100644 index 00000000..4e9e784f --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/geo.php @@ -0,0 +1,132 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Log\Log as JLog; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +require_once dirname(__DIR__) . '/assignment.php'; + +class RLAssignmentsGeo extends RLAssignment +{ + var $geo = null; + + /** + * passContinents + */ + public function passContinents() + { + if ( ! $this->getGeo() || empty($this->geo->continentCode)) + { + return $this->pass(false); + } + + return $this->passSimple([$this->geo->continent, $this->geo->continentCode]); + } + + /** + * passCountries + */ + public function passCountries() + { + $this->getGeo(); + + if ( ! $this->getGeo() || empty($this->geo->countryCode)) + { + return $this->pass(false); + } + + return $this->passSimple([$this->geo->country, $this->geo->countryCode]); + } + + /** + * passRegions + */ + public function passRegions() + { + if ( ! $this->getGeo() || empty($this->geo->countryCode) || empty($this->geo->regionCodes)) + { + return $this->pass(false); + } + + $regions = $this->geo->regionCodes; + array_walk($regions, function (&$value) { + $value = $this->geo->countryCode . '-' . $value; + }); + + return $this->passSimple($regions); + } + + /** + * passPostalcodes + */ + public function passPostalcodes() + { + if ( ! $this->getGeo() || empty($this->geo->postalCode)) + { + return $this->pass(false); + } + + // replace dashes with dots: 730-0011 => 730.0011 + $postalcode = str_replace('-', '.', $this->geo->postalCode); + + return $this->passInRange($postalcode); + } + + public function getGeo($ip = '') + { + if ($this->geo !== null) + { + return $this->geo; + } + + $geo = $this->getGeoObject($ip); + + if (empty($geo)) + { + return false; + } + + $this->geo = $geo->get(); + + if (JDEBUG) + { + JLog::addLogger(['text_file' => 'regularlabs_geoip.log.php'], JLog::ALL, ['regularlabs_geoip']); + JLog::add(json_encode($this->geo), JLog::DEBUG, 'regularlabs_geoip'); + } + + return $this->geo; + } + + private function getGeoObject($ip) + { + if ( ! file_exists(JPATH_LIBRARIES . '/geoip/geoip.php')) + { + return false; + } + + require_once JPATH_LIBRARIES . '/geoip/geoip.php'; + + if ( ! class_exists('RegularLabs_GeoIp')) + { + return new GeoIp($ip); + } + + return new RegularLabs_GeoIp($ip); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments/hikashop.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/hikashop.php new file mode 100644 index 00000000..8ed42f76 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/hikashop.php @@ -0,0 +1,125 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +require_once dirname(__DIR__) . '/assignment.php'; + +class RLAssignmentsHikaShop extends RLAssignment +{ + public function passPageTypes() + { + if ($this->request->option != 'com_hikashop') + { + return $this->pass(false); + } + + $type = $this->request->view; + if ( + ($type == 'product' && in_array($this->request->layout, ['contact', 'show'])) + || ($type == 'user' && in_array($this->request->layout, ['cpanel'])) + ) + { + $type .= '_' . $this->request->layout; + } + + return $this->passSimple($type); + } + + public function passCategories() + { + if ($this->request->option != 'com_hikashop') + { + return $this->pass(false); + } + + $pass = ( + ($this->params->inc_categories + && ($this->request->view == 'category' || $this->request->layout == 'listing') + ) + || ($this->params->inc_items && $this->request->view == 'product') + ); + + if ( ! $pass) + { + return $this->pass(false); + } + + $cats = $this->getCategories(); + + $pass = $this->passSimple($cats, 'include'); + + if ($pass && $this->params->inc_children == 2) + { + return $this->pass(false); + } + else if ( ! $pass && $this->params->inc_children) + { + foreach ($cats as $cat) + { + $cats = array_merge($cats, $this->getCatParentIds($cat)); + } + } + + return $this->passSimple($cats); + } + + public function passProducts() + { + if ( ! $this->request->id || $this->request->option != 'com_hikashop' || $this->request->view != 'product') + { + return $this->pass(false); + } + + return $this->passSimple($this->request->id); + } + + private function getCategories() + { + switch (true) + { + case (($this->request->view == 'category' || $this->request->layout == 'listing') && $this->request->id): + return [$this->request->id]; + + case ($this->request->view == 'category' || $this->request->layout == 'listing'): + include_once JPATH_ADMINISTRATOR . '/components/com_hikashop/helpers/helper.php'; + $menuClass = hikashop_get('class.menus'); + $menuData = $menuClass->get($this->request->Itemid); + + return $this->makeArray($menuData->hikashop_params['selectparentlisting']); + + case ($this->request->id): + $query = $this->db->getQuery(true) + ->select('c.category_id') + ->from('#__hikashop_product_category AS c') + ->where('c.product_id = ' . (int) $this->request->id); + $this->db->setQuery($query); + $cats = $this->db->loadColumn(); + + return $this->makeArray($cats); + + default: + return []; + } + } + + private function getCatParentIds($id = 0) + { + return $this->getParentIds($id, 'hikashop_category', 'category_parent_id', 'category_id'); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments/homepage.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/homepage.php new file mode 100644 index 00000000..3e3d1979 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/homepage.php @@ -0,0 +1,192 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; +use Joomla\CMS\Language\LanguageHelper as JLanguageHelper; +use Joomla\CMS\Uri\Uri as JUri; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +require_once dirname(__DIR__) . '/text.php'; +require_once dirname(__DIR__) . '/string.php'; +require_once dirname(__DIR__) . '/assignment.php'; + +class RLAssignmentsHomePage extends RLAssignment +{ + public function passHomePage() + { + $home = JFactory::getApplication()->getMenu('site')->getDefault(JFactory::getLanguage()->getTag()); + + // return if option or other set values do not match the homepage menu item values + if ($this->request->option) + { + // check if option is different to home menu + if ( ! $home || ! isset($home->query['option']) || $home->query['option'] != $this->request->option) + { + return $this->pass(false); + } + + if ( ! $this->request->option) + { + // set the view/task/layout in the menu item to empty if not set + $home->query['view'] = isset($home->query['view']) ? $home->query['view'] : ''; + $home->query['task'] = isset($home->query['task']) ? $home->query['task'] : ''; + $home->query['layout'] = isset($home->query['layout']) ? $home->query['layout'] : ''; + } + + // check set values against home menu query items + foreach ($home->query as $k => $v) + { + if ((isset($this->request->{$k}) && $this->request->{$k} != $v) + || ( + ( ! isset($this->request->{$k}) || in_array($v, ['virtuemart', 'mijoshop'])) + && JFactory::getApplication()->input->get($k) != $v + ) + ) + { + return $this->pass(false); + } + } + + // check post values against home menu params + foreach ($home->params->toObject() as $k => $v) + { + if (($v && isset($_POST[$k]) && $_POST[$k] != $v) + || ( ! $v && isset($_POST[$k]) && $_POST[$k]) + ) + { + return $this->pass(false); + } + } + } + + $pass = $this->checkPass($home); + + if ( ! $pass) + { + $pass = $this->checkPass($home, 1); + } + + return $this->pass($pass); + } + + private function checkPass(&$home, $addlang = 0) + { + $uri = JUri::getInstance(); + + if ($addlang) + { + $sef = $uri->getVar('lang'); + if (empty($sef)) + { + $langs = array_keys(JLanguageHelper::getLanguages('sef')); + $path = RLString::substr( + $uri->toString(['scheme', 'user', 'pass', 'host', 'port', 'path']), + RLString::strlen($uri->base()) + ); + $path = preg_replace('#^index\.php/?#', '', $path); + $parts = explode('/', $path); + $part = reset($parts); + if (in_array($part, $langs)) + { + $sef = $part; + } + } + + if (empty($sef)) + { + return false; + } + } + + $query = $uri->toString(['query']); + if (strpos($query, 'option=') === false && strpos($query, 'Itemid=') === false) + { + $url = $uri->toString(['host', 'path']); + } + else + { + $url = $uri->toString(['host', 'path', 'query']); + } + + // remove the www. + $url = preg_replace('#^www\.#', '', $url); + // replace ampersand chars + $url = str_replace('&', '&', $url); + // remove any language vars + $url = preg_replace('#((\?)lang=[a-z-_]*(&|$)|&lang=[a-z-_]*)#', '\2', $url); + // remove trailing nonsense + $url = trim(preg_replace('#/?\??&?$#', '', $url)); + // remove the index.php/ + $url = preg_replace('#/index\.php(/|$)#', '/', $url); + // remove trailing / + $url = trim(preg_replace('#/$#', '', $url)); + + $root = JUri::root(); + + // remove the http(s) + $root = preg_replace('#^.*?://#', '', $root); + // remove the www. + $root = preg_replace('#^www\.#', '', $root); + //remove the port + $root = preg_replace('#:[0-9]+#', '', $root); + // so also passes on urls with trailing /, ?, &, /?, etc... + $root = preg_replace('#(Itemid=[0-9]*).*^#', '\1', $root); + // remove trailing / + $root = trim(preg_replace('#/$#', '', $root)); + + if ($addlang) + { + $root .= '/' . $sef; + } + + /* Pass urls: + * [root] + */ + $regex = '#^' . $root . '$#i'; + + if (preg_match($regex, $url)) + { + return true; + } + + /* Pass urls: + * [root]?Itemid=[menu-id] + * [root]/?Itemid=[menu-id] + * [root]/index.php?Itemid=[menu-id] + * [root]/[menu-alias] + * [root]/[menu-alias]?Itemid=[menu-id] + * [root]/index.php?[menu-alias] + * [root]/index.php?[menu-alias]?Itemid=[menu-id] + * [root]/[menu-link] + * [root]/[menu-link]&Itemid=[menu-id] + */ + $regex = '#^' . $root + . '(/(' + . 'index\.php' + . '|' + . '(index\.php\?)?' . RLText::pregQuote($home->alias) + . '|' + . RLText::pregQuote($home->link) + . ')?)?' + . '(/?[\?&]Itemid=' . (int) $home->id . ')?' + . '$#i'; + + return preg_match($regex, $url); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments/ips.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/ips.php new file mode 100644 index 00000000..cd2edba5 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/ips.php @@ -0,0 +1,148 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +require_once dirname(__DIR__) . '/assignment.php'; + +class RLAssignmentsIPs extends RLAssignment +{ + public function passIPs() + { + if (is_array($this->selection)) + { + $this->selection = implode(',', $this->selection); + } + + $this->selection = explode(',', str_replace([' ', "\r", "\n"], ['', '', ','], $this->selection)); + + $pass = $this->checkIPList(); + + return $this->pass($pass); + } + + private function checkIPList() + { + foreach ($this->selection as $range) + { + // Check next range if this one doesn't match + if ( ! $this->checkIP($range)) + { + continue; + } + + // Match found, so return true! + return true; + } + + // No matches found, so return false + return false; + } + + private function checkIP($range) + { + if (empty($range)) + { + return false; + } + + if (strpos($range, '-') !== false) + { + // Selection is an IP range + return $this->checkIPRange($range); + } + + // Selection is a single IP (part) + return $this->checkIPPart($range); + } + + private function checkIPRange($range) + { + $ip = $_SERVER['REMOTE_ADDR']; + + // Return if no IP address can be found (shouldn't happen, but who knows) + if (empty($ip)) + { + return false; + } + + // check if IP is between or equal to the from and to IP range + list($min, $max) = explode('-', trim($range), 2); + + // Return false if IP is smaller than the range start + if ($ip < trim($min)) + { + return false; + } + + $max = $this->fillMaxRange($max, $min); + + // Return false if IP is larger than the range end + if ($ip > trim($max)) + { + return false; + } + + return true; + } + + /* Fill the max range by prefixing it with the missing parts from the min range + * So 101.102.103.104-201.202 becomes: + * max: 101.102.201.202 + */ + private function fillMaxRange($max, $min) + { + $max_parts = explode('.', $max); + + if (count() == 4) + { + return $max; + } + + $min_parts = explode('.', $min); + + $prefix = array_slice($min_parts, 0, count($min_parts) - count($max_parts)); + + return implode('.', $prefix) . '.' . implode('.', $max_parts); + } + + private function checkIPPart($range) + { + $ip = $_SERVER['REMOTE_ADDR']; + + // Return if no IP address can be found (shouldn't happen, but who knows) + if (empty($ip)) + { + return false; + } + + $ip_parts = explode('.', $ip); + $range_parts = explode('.', trim($range)); + + // Trim the IP to the part length of the range + $ip = implode('.', array_slice($ip_parts, 0, count($range_parts))); + + // Return false if ip does not match the range + if ($range != $ip) + { + return false; + } + + return true; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments/k2.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/k2.php new file mode 100644 index 00000000..fc73b892 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/k2.php @@ -0,0 +1,202 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +require_once dirname(__DIR__) . '/assignment.php'; + +// If controller.php exists, assume this is K2 v3 +defined('RL_K2_VERSION') or define('RL_K2_VERSION', JFile::exists(JPATH_ADMINISTRATOR . '/components/com_k2/controller.php') ? 3 : 2); + +class RLAssignmentsK2 extends RLAssignment +{ + public function passPageTypes() + { + return $this->passByPageTypes('com_k2', $this->selection, $this->assignment, false, true); + } + + public function passCategories() + { + if ($this->request->option != 'com_k2') + { + return $this->pass(false); + } + + $pass = ( + ($this->params->inc_categories + && (($this->request->view == 'itemlist' && $this->request->task == 'category') + || $this->request->view == 'latest' + ) + ) + || ($this->params->inc_items && $this->request->view == 'item') + ); + + if ( ! $pass) + { + return $this->pass(false); + } + + $cats = $this->makeArray($this->getCategories()); + $pass = $this->passSimple($cats, 'include'); + + if ($pass && $this->params->inc_children == 2) + { + return $this->pass(false); + } + else if ( ! $pass && $this->params->inc_children) + { + foreach ($cats as $cat) + { + $cats = array_merge($cats, $this->getCatParentIds($cat)); + } + } + + return $this->passSimple($cats); + } + + private function getCategories() + { + switch ($this->request->view) + { + case 'item' : + return $this->getCategoryIDFromItem(); + break; + + case 'itemlist' : + return $this->getCategoryID(); + break; + + default: + return ''; + } + } + + private function getCategoryID() + { + return $this->request->id ?: JFactory::getApplication()->getUserStateFromRequest('com_k2itemsfilter_category', 'catid', 0, 'int'); + } + + private function getCategoryIDFromItem() + { + if ($this->article && isset($this->article->catid)) + { + return $this->article->catid; + } + + $query = $this->db->getQuery(true) + ->select('i.catid') + ->from('#__k2_items AS i') + ->where('i.id = ' . (int) $this->request->id); + $this->db->setQuery($query); + + return $this->db->loadResult(); + } + + public function passTags() + { + if ($this->request->option != 'com_k2') + { + return $this->pass(false); + } + + $tag = trim(JFactory::getApplication()->input->getString('tag', '')); + $pass = ( + ($this->params->inc_tags && $tag != '') + || ($this->params->inc_items && $this->request->view == 'item') + ); + + if ( ! $pass) + { + return $this->pass(false); + } + + if ($this->params->inc_tags && $tag != '') + { + $tags = [trim(JFactory::getApplication()->input->getString('tag', ''))]; + + return $this->passSimple($tags, true); + } + + $query = $this->db->getQuery(true) + ->select('t.name') + ->from('#__k2_tags_xref AS x') + ->join('LEFT', '#__k2_tags AS t ON t.id = x.tagID') + ->where('x.itemID = ' . (int) $this->request->id) + ->where('t.published = 1'); + $this->db->setQuery($query); + $tags = $this->db->loadColumn(); + + return $this->passSimple($tags, true); + } + + public function passItems() + { + if ( ! $this->request->id || $this->request->option != 'com_k2' || $this->request->view != 'item') + { + return $this->pass(false); + } + + $pass = false; + + // Pass Article Id + if ( ! $this->passItemByType($pass, 'ContentIds')) + { + return $this->pass(false); + } + + // Pass Content Keywords + if ( ! $this->passItemByType($pass, 'ContentKeywords')) + { + return $this->pass(false); + } + + // Pass Meta Keywords + if ( ! $this->passItemByType($pass, 'MetaKeywords')) + { + return $this->pass(false); + } + + // Pass Authors + if ( ! $this->passItemByType($pass, 'Authors')) + { + return $this->pass(false); + } + + return $this->pass($pass); + } + + public function getItem($fields = []) + { + $query = $this->db->getQuery(true) + ->select($fields) + ->from('#__k2_items') + ->where('id = ' . (int) $this->request->id); + $this->db->setQuery($query); + + return $this->db->loadObject(); + } + + private function getCatParentIds($id = 0) + { + $parent_field = RL_K2_VERSION == 3 ? 'parent_id' : 'parent'; + + return $this->getParentIds($id, 'k2_categories', $parent_field); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments/languages.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/languages.php new file mode 100644 index 00000000..d7ca1233 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/languages.php @@ -0,0 +1,31 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +require_once dirname(__DIR__) . '/assignment.php'; + +class RLAssignmentsLanguages extends RLAssignment +{ + public function passLanguages() + { + return $this->passSimple(JFactory::getLanguage()->getTag(), true); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments/menu.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/menu.php new file mode 100644 index 00000000..d7123d2c --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/menu.php @@ -0,0 +1,106 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +require_once dirname(__DIR__) . '/assignment.php'; + +class RLAssignmentsMenu extends RLAssignment +{ + public function passMenu() + { + // return if no Itemid or selection is set + if ( ! $this->request->Itemid || empty($this->selection)) + { + return $this->pass($this->params->inc_noitemid); + } + + $menutype = 'type.' . self::getMenuType(); + + // return true if menu type is in selection + if (in_array($menutype, $this->selection)) + { + return $this->pass(true); + } + + // return true if menu is in selection + if (in_array($this->request->Itemid, $this->selection)) + { + return $this->pass(($this->params->inc_children != 2)); + } + + if ( ! $this->params->inc_children) + { + return $this->pass(false); + } + + $parent_ids = $this->getMenuParentIds($this->request->Itemid); + $parent_ids = array_diff($parent_ids, [1]); + foreach ($parent_ids as $id) + { + if ( ! in_array($id, $this->selection)) + { + continue; + } + + return $this->pass(true); + } + + return $this->pass(false); + } + + private function getMenuParentIds($id = 0) + { + return $this->getParentIds($id, 'menu'); + } + + private function getMenuType() + { + if (isset($this->request->menutype)) + { + return $this->request->menutype; + } + + if (empty($this->request->Itemid)) + { + $this->request->menutype = ''; + + return $this->request->menutype; + } + + if (JFactory::getApplication()->isClient('site')) + { + $menu = JFactory::getApplication()->getMenu()->getItem((int) $this->request->Itemid); + + $this->request->menutype = isset($menu->menutype) ? $menu->menutype : ''; + + return $this->request->menutype; + } + + $query = $this->db->getQuery(true) + ->select('m.menutype') + ->from('#__menu AS m') + ->where('m.id = ' . (int) $this->request->Itemid); + $this->db->setQuery($query); + $this->request->menutype = $this->db->loadResult(); + + return $this->request->menutype; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments/mijoshop.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/mijoshop.php new file mode 100644 index 00000000..86399c4d --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/mijoshop.php @@ -0,0 +1,131 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +require_once dirname(__DIR__) . '/assignment.php'; + +class RLAssignmentsMijoShop extends RLAssignment +{ + public function init() + { + $input = JFactory::getApplication()->input; + + $category_id = $input->getCmd('path', 0); + if (strpos($category_id, '_')) + { + $category_id = end(explode('_', $category_id)); + } + + $this->request->item_id = $input->getInt('product_id', 0); + $this->request->category_id = $category_id; + $this->request->id = ($this->request->item_id) ? $this->request->item_id : $this->request->category_id; + + $view = $input->getCmd('view', ''); + if (empty($view)) + { + $mijoshop = JPATH_ROOT . '/components/com_mijoshop/mijoshop/mijoshop.php'; + if ( ! file_exists($mijoshop)) + { + return; + } + + require_once($mijoshop); + + $route = $input->getString('route', ''); + $view = MijoShop::get('router')->getView($route); + } + + $this->request->view = $view; + } + + public function passPageTypes() + { + return $this->passByPageTypes('com_mijoshop', $this->selection, $this->assignment, true); + } + + public function passCategories() + { + if ($this->request->option != 'com_mijoshop') + { + return $this->pass(false); + } + + $pass = ( + ($this->params->inc_categories + && ($this->request->view == 'category') + ) + || ($this->params->inc_items && $this->request->view == 'product') + ); + + if ( ! $pass) + { + return $this->pass(false); + } + + $cats = []; + if ($this->request->category_id) + { + $cats = $this->request->category_id; + } + else if ($this->request->item_id) + { + $query = $this->db->getQuery(true) + ->select('c.category_id') + ->from('#__mijoshop_product_to_category AS c') + ->where('c.product_id = ' . (int) $this->request->id); + $this->db->setQuery($query); + $cats = $this->db->loadColumn(); + } + + $cats = $this->makeArray($cats); + + $pass = $this->passSimple($cats, 'include'); + + if ($pass && $this->params->inc_children == 2) + { + return $this->pass(false); + } + else if ( ! $pass && $this->params->inc_children) + { + foreach ($cats as $cat) + { + $cats = array_merge($cats, $this->getCatParentIds($cat)); + } + } + + return $this->passSimple($cats); + } + + public function passProducts() + { + if ( ! $this->request->id || $this->request->option != 'com_mijoshop' || $this->request->view != 'product') + { + return $this->pass(false); + } + + return $this->passSimple($this->request->id); + } + + private function getCatParentIds($id = 0) + { + return $this->getParentIds($id, 'mijoshop_category', 'parent_id', 'category_id'); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments/php.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/php.php new file mode 100644 index 00000000..7afddf12 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/php.php @@ -0,0 +1,131 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; +use Joomla\CMS\MVC\Model\BaseDatabaseModel as JModel; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +require_once dirname(__DIR__) . '/assignment.php'; + +class RLAssignmentsPHP extends RLAssignment +{ + public function passPHP() + { + $article = $this->article; + + if ( ! is_array($this->selection)) + { + $this->selection = [$this->selection]; + } + + $pass = false; + foreach ($this->selection as $php) + { + // replace \n with newline and other fix stuff + $php = str_replace('\|', '|', $php); + $php = preg_replace('#(?request->option == 'com_content' && $this->request->view == 'article') + { + $article = $this->getArticleById($this->request->id); + } + } + if ( ! isset($Itemid)) + { + $Itemid = JFactory::getApplication()->input->getInt('Itemid', 0); + } + if ( ! isset($mainframe)) + { + $mainframe = JFactory::getApplication(); + } + if ( ! isset($app)) + { + $app = JFactory::getApplication(); + } + if ( ! isset($document)) + { + $document = JFactory::getDocument(); + } + if ( ! isset($doc)) + { + $doc = JFactory::getDocument(); + } + if ( ! isset($database)) + { + $database = JFactory::getDbo(); + } + if ( ! isset($db)) + { + $db = JFactory::getDbo(); + } + if ( ! isset($user)) + { + $user = JFactory::getUser(); + } + $php .= ';return true;'; + + $temp_PHP_func = create_function('&$article, &$Itemid, &$mainframe, &$app, &$document, &$doc, &$database, &$db, &$user', $php); + + // evaluate the script + ob_start(); + $pass = (bool) $temp_PHP_func($article, $Itemid, $mainframe, $app, $document, $doc, $database, $db, $user); + unset($temp_PHP_func); + ob_end_clean(); + + if ($pass) + { + break; + } + } + + return $this->pass($pass); + } + + private function getArticleById($id = 0) + { + if ( ! $id) + { + return null; + } + + if ( ! class_exists('ContentModelArticle')) + { + require_once JPATH_SITE . '/components/com_content/models/article.php'; + } + + $model = JModel::getInstance('article', 'contentModel'); + + if ( ! method_exists($model, 'getItem')) + { + return null; + } + + return $model->getItem($this->request->id); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments/redshop.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/redshop.php new file mode 100644 index 00000000..daed3a09 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/redshop.php @@ -0,0 +1,106 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +require_once dirname(__DIR__) . '/assignment.php'; + +class RLAssignmentsRedShop extends RLAssignment +{ + public function init() + { + $this->request->item_id = JFactory::getApplication()->input->getInt('pid', 0); + $this->request->category_id = JFactory::getApplication()->input->getInt('cid', 0); + $this->request->id = ($this->request->item_id) ? $this->request->item_id : $this->request->category_id; + } + + public function passPageTypes() + { + return $this->passByPageTypes('com_redshop', $this->selection, $this->assignment, true); + } + + public function passCategories() + { + if ($this->request->option != 'com_redshop') + { + return $this->pass(false); + } + + $pass = ( + ($this->params->inc_categories + && ($this->request->view == 'category') + ) + || ($this->params->inc_items && $this->request->view == 'product') + ); + + if ( ! $pass) + { + return $this->pass(false); + } + + $cats = []; + if ($this->request->category_id) + { + $cats = $this->request->category_id; + } + else if ($this->request->item_id) + { + $query = $this->db->getQuery(true) + ->select('x.category_id') + ->from('#__redshop_product_category_xref AS x') + ->where('x.product_id = ' . (int) $this->request->item_id); + $this->db->setQuery($query); + $cats = $this->db->loadColumn(); + } + + $cats = $this->makeArray($cats); + + $pass = $this->passSimple($cats, 'include'); + + if ($pass && $this->params->inc_children == 2) + { + return $this->pass(false); + } + else if ( ! $pass && $this->params->inc_children) + { + foreach ($cats as $cat) + { + $cats = array_merge($cats, $this->getCatParentIds($cat)); + } + } + + return $this->passSimple($cats); + } + + public function passProducts() + { + if ( ! $this->request->id || $this->request->option != 'com_redshop' || $this->request->view != 'product') + { + return $this->pass(false); + } + + return $this->passSimple($this->request->id); + } + + private function getCatParentIds($id = 0) + { + return $this->getParentIds($id, 'redshop_category_xref', 'category_parent_id', 'category_child_id'); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments/tags.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/tags.php new file mode 100644 index 00000000..73db7baf --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/tags.php @@ -0,0 +1,125 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +require_once dirname(__DIR__) . '/assignment.php'; + +class RLAssignmentsTags extends RLAssignment +{ + public function passTags() + { + if (in_array($this->request->option, ['com_content', 'com_flexicontent'])) + { + return $this->passTagsContent(); + } + + if ($this->request->option != 'com_tags' + || $this->request->view != 'tag' + || ! $this->request->id + ) + { + return $this->pass(false); + } + + return $this->passTag($this->request->id); + } + + private function passTagsContent() + { + $is_item = in_array($this->request->view, ['', 'article', 'item']); + $is_category = in_array($this->request->view, ['category']); + + switch (true) + { + case ($is_item): + $prefix = 'com_content.article'; + break; + + case ($is_category): + $prefix = 'com_content.category'; + break; + + default: + return $this->pass(false); + } + + // Load the tags. + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('t.id')) + ->select($this->db->quoteName('t.title')) + ->from('#__tags AS t') + ->join( + 'INNER', '#__contentitem_tag_map AS m' + . ' ON m.tag_id = t.id' + . ' AND m.type_alias = ' . $this->db->quote($prefix) + . ' AND m.content_item_id IN ( ' . $this->request->id . ')' + ); + $this->db->setQuery($query); + $tags = $this->db->loadObjectList(); + + if (empty($tags)) + { + return $this->pass(false); + } + + foreach ($tags as $tag) + { + if ( ! $this->passTag($tag->id) && ! $this->passTag($tag->title)) + { + continue; + } + + return $this->pass(true); + } + + return $this->pass(false); + } + + private function passTag($tag) + { + $pass = in_array($tag, $this->selection); + + if ($pass) + { + // If passed, return false if assigned to only children + // Else return true + return ($this->params->inc_children != 2); + } + + if ( ! $this->params->inc_children) + { + return false; + } + + // Return true if a parent id is present in the selection + return array_intersect( + $this->getTagsParentIds($tag), + $this->selection + ); + } + + private function getTagsParentIds($id = 0) + { + $parentids = $this->getParentIds($id, 'tags'); + // Remove the root tag + $parentids = array_diff($parentids, [1]); + + return $parentids; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments/templates.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/templates.php new file mode 100644 index 00000000..80555516 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/templates.php @@ -0,0 +1,73 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +require_once dirname(__DIR__) . '/assignment.php'; + +class RLAssignmentsTemplates extends RLAssignment +{ + public function passTemplates() + { + $template = $this->getTemplate(); + + // Put template name and name + style id into array + // The '::' separator was used in pre Joomla 3.3 + $template = [$template->template, $template->template . '--' . $template->id, $template->template . '::' . $template->id]; + + return $this->passSimple($template, true); + } + + public function getTemplate() + { + $template = JFactory::getApplication()->getTemplate(true); + + if (isset($template->id)) + { + return $template; + } + + $params = json_encode($template->params); + + // Find template style id based on params, as the template style id is not always stored in the getTemplate + $query = $this->db->getQuery(true) + ->select('id') + ->from('#__template_styles as s') + ->where('s.client_id = 0') + ->where('s.template = ' . $this->db->quote($template->template)) + ->where('s.params = ' . $this->db->quote($params)); + $this->db->setQuery($query, 0, 1); + $template->id = $this->db->loadResult('id'); + + if ($template->id) + { + return $template; + } + + // No template style id is found, so just grab the first result based on the template name + $query->clear('where') + ->where('s.client_id = 0') + ->where('s.template = ' . $this->db->quote($template->template)); + $this->db->setQuery($query, 0, 1); + $template->id = $this->db->loadResult('id'); + + return $template; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments/urls.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/urls.php new file mode 100644 index 00000000..960d033d --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/urls.php @@ -0,0 +1,92 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Uri\Uri as JUri; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +require_once dirname(__DIR__) . '/assignment.php'; +require_once dirname(__DIR__) . '/text.php'; + +class RLAssignmentsURLs extends RLAssignment +{ + public function passURLs() + { + $regex = isset($this->params->regex) ? $this->params->regex : 0; + + if ( ! is_array($this->selection)) + { + $this->selection = explode("\n", $this->selection); + } + + if (count($this->selection) == 1) + { + $this->selection = explode("\n", $this->selection[0]); + } + + $url = JUri::getInstance(); + $url = $url->toString(); + + $urls = [ + RLText::html_entity_decoder(urldecode($url)), + urldecode($url), + RLText::html_entity_decoder($url), + $url, + ]; + $urls = array_unique($urls); + + $pass = false; + foreach ($urls as $url) + { + foreach ($this->selection as $s) + { + $s = trim($s); + if ($s == '') + { + continue; + } + + if ($regex) + { + $url_part = str_replace(['#', '&'], ['\#', '(&|&)'], $s); + $s = '#' . $url_part . '#si'; + if (@preg_match($s . 'u', $url) || @preg_match($s, $url)) + { + $pass = true; + break; + } + + continue; + } + + if (strpos($url, $s) !== false) + { + $pass = true; + break; + } + } + + if ($pass) + { + break; + } + } + + return $this->pass($pass); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments/users.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/users.php new file mode 100644 index 00000000..f8c33728 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/users.php @@ -0,0 +1,175 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +require_once dirname(__DIR__) . '/assignment.php'; + +class RLAssignmentsUsers extends RLAssignment +{ + public function passAccessLevels() + { + $user = JFactory::getUser(); + + $levels = $user->getAuthorisedViewLevels(); + + $this->selection = $this->convertAccessLevelNamesToIds($this->selection); + + return $this->passSimple($levels); + } + + public function passUserGroupLevels() + { + $user = JFactory::getUser(); + + if ( ! empty($user->groups)) + { + $groups = array_values($user->groups); + } + else + { + $groups = $user->getAuthorisedGroups(); + } + + if ($this->params->inc_children) + { + $this->setUserGroupChildrenIds(); + } + + $this->selection = $this->convertUsergroupNamesToIds($this->selection); + + return $this->passSimple($groups); + } + + public function passUsers() + { + return $this->passSimple(JFactory::getUser()->get('id')); + } + + private function convertAccessLevelNamesToIds($selection) + { + $names = []; + + foreach ($selection as $i => $level) + { + if (is_numeric($level)) + { + continue; + } + + unset($selection[$i]); + + $names[] = strtolower(str_replace(' ', '', $level)); + } + + $db = JFactory::getDbo(); + + $query = $db->getQuery(true) + ->select($db->quoteName('id')) + ->from('#__viewlevels') + ->where('LOWER(REPLACE(' . $db->quoteName('title') . ', " ", "")) IN (\'' . implode('\',\'', $names) . '\')'); + $db->setQuery($query); + + $level_ids = $db->loadColumn(); + + return array_unique(array_merge($selection, $level_ids)); + } + + private function convertUsergroupNamesToIds($selection) + { + $names = []; + + foreach ($selection as $i => $group) + { + if (is_numeric($group)) + { + continue; + } + + unset($selection[$i]); + + $names[] = strtolower(str_replace(' ', '', $group)); + } + + $db = JFactory::getDbo(); + + $query = $db->getQuery(true) + ->select($db->quoteName('id')) + ->from('#__usergroups') + ->where('LOWER(REPLACE(' . $db->quoteName('title') . ', " ", "")) IN (\'' . implode('\',\'', $names) . '\')'); + $db->setQuery($query); + + $group_ids = $db->loadColumn(); + + return array_unique(array_merge($selection, $group_ids)); + } + + private function setUserGroupChildrenIds() + { + $children = $this->getUserGroupChildrenIds($this->selection); + + if ($this->params->inc_children == 2) + { + $this->selection = $children; + + return; + } + + $this->selection = array_merge($this->selection, $children); + } + + private function getUserGroupChildrenIds($groups) + { + $children = []; + + $db = JFactory::getDbo(); + + foreach ($groups as $group) + { + $query = $db->getQuery(true) + ->select($db->quoteName('id')) + ->from($db->quoteName('#__usergroups')) + ->where($db->quoteName('parent_id') . ' = ' . (int) $group); + $db->setQuery($query); + + $group_children = $db->loadColumn(); + + if (empty($group_children)) + { + continue; + } + + $children = array_merge($children, $group_children); + + $group_grand_children = $this->getUserGroupChildrenIds($group_children); + + if (empty($group_grand_children)) + { + continue; + } + + $children = array_merge($children, $group_grand_children); + } + + $children = array_unique($children); + + return $children; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments/virtuemart.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/virtuemart.php new file mode 100644 index 00000000..379b0cce --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/virtuemart.php @@ -0,0 +1,142 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +require_once dirname(__DIR__) . '/assignment.php'; + +class RLAssignmentsVirtueMart extends RLAssignment +{ + public function init() + { + $virtuemart_product_id = JFactory::getApplication()->input->get('virtuemart_product_id', [], 'array'); + $virtuemart_category_id = JFactory::getApplication()->input->get('virtuemart_category_id', [], 'array'); + + $this->request->item_id = isset($virtuemart_product_id[0]) ? $virtuemart_product_id[0] : null; + $this->request->category_id = isset($virtuemart_category_id[0]) ? $virtuemart_category_id[0] : null; + $this->request->id = ($this->request->item_id) ? $this->request->item_id : $this->request->category_id; + } + + public function passPageTypes() + { + // Because VM sucks, we have to get the view again + $this->request->view = JFactory::getApplication()->input->getString('view'); + + return $this->passByPageTypes('com_virtuemart', $this->selection, $this->assignment, true); + } + + public function passCategories() + { + if ($this->request->option != 'com_virtuemart') + { + return $this->pass(false); + } + + // Because VM sucks, we have to get the view again + $this->request->view = JFactory::getApplication()->input->getString('view'); + + $pass = (($this->params->inc_categories && in_array($this->request->view, ['categories', 'category'])) + || ($this->params->inc_items && $this->request->view == 'productdetails') + ); + + if ( ! $pass) + { + return $this->pass(false); + } + + $cats = []; + if ($this->request->view == 'productdetails' && $this->request->item_id) + { + $query = $this->db->getQuery(true) + ->select('x.virtuemart_category_id') + ->from('#__virtuemart_product_categories AS x') + ->where('x.virtuemart_product_id = ' . (int) $this->request->item_id); + $this->db->setQuery($query); + $cats = $this->db->loadColumn(); + } + else if ($this->request->category_id) + { + $cats = $this->request->category_id; + if ( ! is_numeric($cats)) + { + $query = $this->db->getQuery(true) + ->select('config') + ->from('#__virtuemart_configs') + ->where('virtuemart_config_id = 1'); + $this->db->setQuery($query); + $config = $this->db->loadResult(); + $lang = substr($config, strpos($config, 'vmlang=')); + $lang = substr($lang, 0, strpos($lang, '|')); + if (preg_match('#"([^"]*_[^"]*)"#', $lang, $lang)) + { + $lang = $lang[1]; + } + else + { + $lang = 'en_gb'; + } + + $query = $this->db->getQuery(true) + ->select('l.virtuemart_category_id') + ->from('#__virtuemart_categories_' . $lang . ' AS l') + ->where('l.slug = ' . $this->db->quote($cats)); + $this->db->setQuery($query); + $cats = $this->db->loadResult(); + } + } + + $cats = $this->makeArray($cats); + + $pass = $this->passSimple($cats, 'include'); + + if ($pass && $this->params->inc_children == 2) + { + return $this->pass(false); + } + + if ( ! $pass && $this->params->inc_children) + { + foreach ($cats as $cat) + { + $cats = array_merge($cats, $this->getCatParentIds($cat)); + } + } + + return $this->passSimple($cats); + } + + public function passProducts() + { + // Because VM sucks, we have to get the view again + $this->request->view = JFactory::getApplication()->input->getString('view'); + + if ( ! $this->request->id || $this->request->option != 'com_virtuemart' || $this->request->view != 'productdetails') + { + return $this->pass(false); + } + + return $this->passSimple($this->request->id); + } + + private function getCatParentIds($id = 0) + { + return $this->getParentIds($id, 'virtuemart_category_categories', 'category_parent_id', 'category_child_id'); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/assignments/zoo.php b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/zoo.php new file mode 100644 index 00000000..251b5a6e --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/assignments/zoo.php @@ -0,0 +1,290 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +require_once dirname(__DIR__) . '/assignment.php'; + +class RLAssignmentsZoo extends RLAssignment +{ + public function init() + { + if ( ! $this->request->view) + { + $this->request->view = $this->request->task; + } + + switch ($this->request->view) + { + case 'item': + $this->request->idname = 'item_id'; + break; + case 'category': + $this->request->idname = 'category_id'; + break; + } + + $this->request->id = JFactory::getApplication()->input->getInt($this->request->idname, 0); + } + + public function initAssignment($assignment, $article = 0) + { + parent::initAssignment($assignment, $article); + + if ($this->request->option != 'com_zoo' && ! isset($this->request->idname)) + { + return; + } + + switch ($this->request->idname) + { + case 'item_id': + $this->request->view = 'item'; + break; + case 'category_id': + $this->request->view = 'category'; + break; + } + } + + public function passPageTypes() + { + return $this->passByPageTypes('com_zoo', $this->selection, $this->assignment); + } + + public function passCategories() + { + if ($this->request->option != 'com_zoo') + { + return $this->pass(false); + } + + $pass = ( + ($this->params->inc_apps && $this->request->view == 'frontpage') + || ($this->params->inc_categories && $this->request->view == 'category') + || ($this->params->inc_items && $this->request->view == 'item') + ); + + if ( ! $pass) + { + return $this->pass(false); + } + + $cats = $this->getCategories(); + + if ($cats === false) + { + return $this->pass(false); + } + + $cats = $this->makeArray($cats); + + $pass = $this->passSimple($cats, 'include'); + + if ($pass && $this->params->inc_children == 2) + { + return $this->pass(false); + } + + if ( ! $pass && $this->params->inc_children) + { + foreach ($cats as $cat) + { + $cats = array_merge($cats, $this->getCatParentIds($cat)); + } + } + + return $this->passSimple($cats); + } + + private function getCategories() + { + if ($this->article && isset($this->article->catid)) + { + return [$this->article->catid]; + } + + $menuparams = $this->getMenuItemParams($this->request->Itemid); + + switch ($this->request->view) + { + case 'frontpage': + if ($this->request->id) + { + return [$this->request->id]; + } + + if ( ! isset($menuparams->application)) + { + return []; + } + + return ['app' . $menuparams->application]; + + case 'category': + $cats = []; + + if ($this->request->id) + { + $cats[] = $this->request->id; + } + else if (isset($menuparams->category)) + { + $cats[] = $menuparams->category; + } + + if (empty($cats[0])) + { + return []; + } + + $query = $this->db->getQuery(true) + ->select('c.application_id') + ->from('#__zoo_category AS c') + ->where('c.id = ' . (int) $cats[0]); + $this->db->setQuery($query); + $cats[] = 'app' . $this->db->loadResult(); + + return $cats; + + case 'item': + $id = $this->request->id; + + if ( ! $id && isset($menuparams->item_id)) + { + $id = $menuparams->item_id; + } + + if ( ! $id) + { + return []; + } + + $query = $this->db->getQuery(true) + ->select('c.category_id') + ->from('#__zoo_category_item AS c') + ->where('c.item_id = ' . (int) $id) + ->where('c.category_id != 0'); + $this->db->setQuery($query); + $cats = $this->db->loadColumn(); + + $query = $this->db->getQuery(true) + ->select('i.application_id') + ->from('#__zoo_item AS i') + ->where('i.id = ' . (int) $id); + $this->db->setQuery($query); + $cats[] = 'app' . $this->db->loadResult(); + + return $cats; + + default: + return false; + } + } + + public function passItems() + { + if ( ! $this->request->id || $this->request->option != 'com_zoo') + { + return $this->pass(false); + } + + if ($this->request->view != 'item') + { + return $this->pass(false); + } + + $pass = false; + + // Pass Article Id + if ( ! $this->passItemByType($pass, 'ContentIds')) + { + return $this->pass(false); + } + + // Pass Authors + if ( ! $this->passItemByType($pass, 'Authors')) + { + return $this->pass(false); + } + + return $this->pass($pass); + } + + public function getItem($fields = []) + { + $query = $this->db->getQuery(true) + ->select($fields) + ->from('#__zoo_item') + ->where('id = ' . (int) $this->request->id); + $this->db->setQuery($query); + + return $this->db->loadObject(); + } + + private function getCatParentIds($id = 0) + { + $parent_ids = []; + + if ( ! $id) + { + return $parent_ids; + } + + while ($id) + { + if (substr($id, 0, 3) == 'app') + { + $parent_ids[] = $id; + break; + } + + $query = $this->db->getQuery(true) + ->select('c.parent') + ->from('#__zoo_category AS c') + ->where('c.id = ' . (int) $id); + $this->db->setQuery($query); + $pid = $this->db->loadResult(); + + if ( ! $pid) + { + $query = $this->db->getQuery(true) + ->select('c.application_id') + ->from('#__zoo_category AS c') + ->where('c.id = ' . (int) $id); + $this->db->setQuery($query); + $app = $this->db->loadResult(); + + if ($app) + { + $parent_ids[] = 'app' . $app; + } + + break; + } + + $parent_ids[] = $pid; + + $id = $pid; + } + + return $parent_ids; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/cache.php b/deployed/regularlabs/libraries/regularlabs/helpers/cache.php new file mode 100644 index 00000000..a6a37d88 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/cache.php @@ -0,0 +1,51 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use RegularLabs\Library\Cache as RL_Cache; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +class RLCache +{ + static $cache = []; + + public static function has($id) + { + return RL_Cache::has($id); + } + + public static function get($id) + { + return RL_Cache::get($id); + } + + public static function set($id, $data) + { + return RL_Cache::set($id, $data); + } + + public static function read($id) + { + return RL_Cache::read($id); + } + + public static function write($id, $data, $ttl = 0) + { + return RL_Cache::write($id, $data, $ttl); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/field.php b/deployed/regularlabs/libraries/regularlabs/helpers/field.php new file mode 100644 index 00000000..2284f8b9 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/field.php @@ -0,0 +1,24 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +class RLFormField + extends \RegularLabs\Library\Field +{ +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/functions.php b/deployed/regularlabs/libraries/regularlabs/helpers/functions.php new file mode 100644 index 00000000..5c9bac97 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/functions.php @@ -0,0 +1,150 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use RegularLabs\Library\Document as RL_Document; +use RegularLabs\Library\Extension as RL_Extension; +use RegularLabs\Library\File as RL_File; +use RegularLabs\Library\Http as RL_Http; +use RegularLabs\Library\Language as RL_Language; +use RegularLabs\Library\Xml as RL_Xml; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +/** + * Framework Functions + */ +class RLFunctions +{ + public static function getContents($url, $timeout = 20) + { + return ! class_exists('RegularLabs\Library\Http') ? '' : RL_Http::get($url, $timeout); + } + + public static function getByUrl($url, $timeout = 20) + { + return ! class_exists('RegularLabs\Library\Http') ? '' : RL_Http::getFromServer($url, $timeout); + } + + public static function isFeed() + { + return class_exists('RegularLabs\Library\Document') && RL_Document::isFeed(); + } + + public static function script($file, $version = '') + { + class_exists('RegularLabs\Library\Document') && RL_Document::script($file, $version); + } + + public static function stylesheet($file, $version = '') + { + class_exists('RegularLabs\Library\Document') && RL_Document::stylesheet($file, $version); + } + + public static function addScriptVersion($url) + { + jimport('joomla.filesystem.file'); + + $version = ''; + + if (JFile::exists(JPATH_SITE . $url)) + { + $version = filemtime(JPATH_SITE . $url); + } + + self::script($url, $version); + } + + public static function addStyleSheetVersion($url) + { + jimport('joomla.filesystem.file'); + + $version = ''; + + if (JFile::exists(JPATH_SITE . $url)) + { + $version = filemtime(JPATH_SITE . $url); + } + + self::stylesheet($url, $version); + } + + protected static function getFileByFolder($folder, $file) + { + return ! class_exists('RegularLabs\Library\File') ? '' : RL_File::getMediaFile($folder, $file); + } + + public static function getComponentBuffer() + { + return ! class_exists('RegularLabs\Library\Document') ? '' : RL_Document::getBuffer(); + } + + public static function getAliasAndElement(&$name) + { + return ! class_exists('RegularLabs\Library\Extension') ? '' : RL_Extension::getAliasAndElement($name); + } + + public static function getNameByAlias($alias) + { + return ! class_exists('RegularLabs\Library\Extension') ? '' : RL_Extension::getNameByAlias($alias); + } + + public static function getAliasByName($name) + { + return ! class_exists('RegularLabs\Library\Extension') ? '' : RL_Extension::getAliasByName($name); + } + + public static function getElementByAlias($alias) + { + return ! class_exists('RegularLabs\Library\Extension') ? '' : RL_Extension::getElementByAlias($alias); + } + + public static function getXMLValue($key, $alias, $type = 'component', $folder = 'system') + { + return ! class_exists('RegularLabs\Library\Extension') ? '' : RL_Extension::getXMLValue($key, $alias, $type, $folder); + } + + public static function getXML($alias, $type = 'component', $folder = 'system') + { + return ! class_exists('RegularLabs\Library\Extension') ? '' : RL_Extension::getXML($alias, $type, $folder); + } + + public static function getXMLFile($alias, $type = 'component', $folder = 'system') + { + return ! class_exists('RegularLabs\Library\Extension') ? '' : RL_Extension::getXMLFile($alias, $type, $folder); + } + + public static function extensionInstalled($extension, $type = 'component', $folder = 'system') + { + return ! class_exists('RegularLabs\Library\Extension') ? '' : RL_Extension::isInstalled($extension, $type, $folder); + } + + public static function getExtensionPath($extension = 'plg_system_regularlabs', $basePath = JPATH_ADMINISTRATOR, $check_folder = '') + { + return ! class_exists('RegularLabs\Library\Extension') ? '' : RL_Extension::getPath($extension, $basePath, $check_folder); + } + + public static function loadLanguage($extension = 'plg_system_regularlabs', $basePath = '', $reload = false) + { + return class_exists('RegularLabs\Library\Language') && RL_Language::load($extension, $basePath, $reload); + } + + public static function xmlToObject($url, $root = '') + { + return ! class_exists('RegularLabs\Library\Xml') ? '' : RL_Xml::toObject($url, $root); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/groupfield.php b/deployed/regularlabs/libraries/regularlabs/helpers/groupfield.php new file mode 100644 index 00000000..8da110b0 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/groupfield.php @@ -0,0 +1,24 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +class RLFormGroupField + extends \RegularLabs\Library\FieldGroup +{ +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/helper.php b/deployed/regularlabs/libraries/regularlabs/helpers/helper.php new file mode 100644 index 00000000..d3809334 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/helper.php @@ -0,0 +1,70 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use RegularLabs\Library\Article as RL_Article; +use RegularLabs\Library\Cache as RL_Cache; +use RegularLabs\Library\Document as RL_Document; +use RegularLabs\Library\Parameters as RL_Parameters; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +class RLHelper +{ + public static function getPluginHelper($plugin, $params = null) + { + if ( ! class_exists('RegularLabs\Library\Cache')) + { + return null; + } + + $hash = md5('getPluginHelper_' . $plugin->get('_type') . '_' . $plugin->get('_name') . '_' . json_encode($params)); + + if (RL_Cache::has($hash)) + { + return RL_Cache::get($hash); + } + + if ( ! $params) + { + $params = RL_Parameters::getInstance()->getPluginParams($plugin->get('_name')); + } + + $file = JPATH_PLUGINS . '/' . $plugin->get('_type') . '/' . $plugin->get('_name') . '/helper.php'; + + if ( ! is_file($file)) + { + return null; + } + + require_once $file; + $class = get_class($plugin) . 'Helper'; + + return RL_Cache::set( + $hash, + new $class($params) + ); + } + + public static function processArticle(&$article, &$context, &$helper, $method, $params = []) + { + class_exists('RegularLabs\Library\Article') && RL_Article::process($article, $context, $helper, $method, $params); + } + + public static function isCategoryList($context) + { + return class_exists('RegularLabs\Library\Document') && RL_Document::isCategoryList($context); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/html.php b/deployed/regularlabs/libraries/regularlabs/helpers/html.php new file mode 100644 index 00000000..c6c19f9a --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/html.php @@ -0,0 +1,34 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use RegularLabs\Library\Form as RL_Form; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +class RLHtml +{ + static function selectlist(&$options, $name, $value, $id, $size = 0, $multiple = 0, $simple = 0) + { + return RL_Form::selectList($options, $name, $value, $id, $size, $multiple, $simple); + } + + static function selectlistsimple(&$options, $name, $value, $id, $size = 0, $multiple = 0) + { + return RL_Form::selectListSimple($options, $name, $value, $id, $size, $multiple); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/htmlfix.php b/deployed/regularlabs/libraries/regularlabs/helpers/htmlfix.php new file mode 100644 index 00000000..68a36a53 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/htmlfix.php @@ -0,0 +1,29 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use RegularLabs\Library\Html as RL_Html; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +class RLHtmlFix +{ + public static function _($string) + { + return RL_Html::fix($string); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/licenses.php b/deployed/regularlabs/libraries/regularlabs/helpers/licenses.php new file mode 100644 index 00000000..d7d0c497 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/licenses.php @@ -0,0 +1,29 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use RegularLabs\Library\License as RL_License; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +class RLLicenses +{ + public static function render($name, $check_pro = false) + { + return ! class_exists('RegularLabs\Library\License') ? '' : RL_License::getMessage($name, $check_pro); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/mobile_detect.php b/deployed/regularlabs/libraries/regularlabs/helpers/mobile_detect.php new file mode 100644 index 00000000..9ecba8e2 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/mobile_detect.php @@ -0,0 +1,23 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +class RLMobile_Detect extends \RegularLabs\Library\MobileDetect +{ +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/parameters.php b/deployed/regularlabs/libraries/regularlabs/helpers/parameters.php new file mode 100644 index 00000000..aa61c731 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/parameters.php @@ -0,0 +1,29 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use RegularLabs\Library\Parameters as RL_Parameters; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +class RLParameters +{ + public static function getInstance() + { + return RL_Parameters::getInstance(); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/protect.php b/deployed/regularlabs/libraries/regularlabs/helpers/protect.php new file mode 100644 index 00000000..98cce821 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/protect.php @@ -0,0 +1,195 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use RegularLabs\Library\Document as RL_Document; +use RegularLabs\Library\Protect as RL_Protect; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +class RLProtect +{ + public static function isProtectedPage($extension_alias = '', $hastags = false, $exclude_formats = ['pdf']) + { + if ( ! class_exists('RegularLabs\Library\Protect')) + { + return true; + } + + if (RL_Protect::isDisabledByUrl($extension_alias)) + { + return true; + } + + return class_exists('RegularLabs\Library\Protect') && RL_Protect::isRestrictedPage($hastags, $exclude_formats); + } + + public static function isAdmin($block_login = false) + { + return class_exists('RegularLabs\Library\Document') && RL_Document::isAdmin($block_login); + } + + public static function isEditPage() + { + return class_exists('RegularLabs\Library\Document') && RL_Document::isEditPage(); + } + + public static function isRestrictedComponent($restricted_components, $area = 'component') + { + return class_exists('RegularLabs\Library\Protect') && RL_Protect::isRestrictedComponent($restricted_components, $area); + } + + public static function isComponentInstalled($extension_alias) + { + return class_exists('RegularLabs\Library\Protect') && RL_Protect::isComponentInstalled($extension_alias); + } + + public static function isSystemPluginInstalled($extension_alias) + { + return class_exists('RegularLabs\Library\Protect') && RL_Protect::isSystemPluginInstalled($extension_alias); + } + + public static function getFormRegex($regex_format = false) + { + return class_exists('RegularLabs\Library\Protect') && RL_Protect::getFormRegex($regex_format); + } + + public static function protectFields(&$string, $search_strings = []) + { + class_exists('RegularLabs\Library\Protect') && RL_Protect::protectFields($string, $search_strings); + } + + public static function protectScripts(&$string) + { + class_exists('RegularLabs\Library\Protect') && RL_Protect::protectScripts($string); + } + + public static function protectHtmlTags(&$string) + { + class_exists('RegularLabs\Library\Protect') && RL_Protect::protectHtmlTags($string); + } + + public static function protectByRegex(&$string, $regex) + { + class_exists('RegularLabs\Library\Protect') && RL_Protect::protectByRegex($string, $regex); + } + + public static function protectTags(&$string, $tags = [], $include_closing_tags = true) + { + class_exists('RegularLabs\Library\Protect') && RL_Protect::protectTags($string, $tags, $include_closing_tags); + } + + public static function unprotectTags(&$string, $tags = [], $include_closing_tags = true) + { + class_exists('RegularLabs\Library\Protect') && RL_Protect::unprotectTags($string, $tags, $include_closing_tags); + } + + public static function protectInString(&$string, $unprotected = [], $protected = []) + { + class_exists('RegularLabs\Library\Protect') && RL_Protect::protectInString($string, $unprotected, $protected); + } + + public static function unprotectInString(&$string, $unprotected = [], $protected = []) + { + class_exists('RegularLabs\Library\Protect') && RL_Protect::unprotectInString($string, $unprotected, $protected); + } + + public static function protectSourcerer(&$string) + { + class_exists('RegularLabs\Library\Protect') && RL_Protect::protectSourcerer($string); + } + + public static function protectForm(&$string, $tags = [], $include_closing_tags = true) + { + class_exists('RegularLabs\Library\Protect') && RL_Protect::protectForm($string, $tags, $include_closing_tags); + } + + public static function unprotect(&$string) + { + class_exists('RegularLabs\Library\Protect') && RL_Protect::unprotect($string); + } + + public static function convertProtectionToHtmlSafe(&$string) + { + class_exists('RegularLabs\Library\Protect') && RL_Protect::convertProtectionToHtmlSafe($string); + } + + public static function unprotectHtmlSafe(&$string) + { + class_exists('RegularLabs\Library\Protect') && RL_Protect::unprotectHtmlSafe($string); + } + + public static function protectString($string, $is_tag = false) + { + return class_exists('RegularLabs\Library\Protect') && RL_Protect::protectString($string, $is_tag); + } + + public static function unprotectString($string, $is_tag = false) + { + return class_exists('RegularLabs\Library\Protect') && RL_Protect::unprotectString($string, $is_tag); + } + + public static function protectTag($string) + { + return class_exists('RegularLabs\Library\Protect') && RL_Protect::protectTag($string); + } + + public static function protectArray($array, $is_tag = false) + { + return class_exists('RegularLabs\Library\Protect') && RL_Protect::protectArray($array, $is_tag); + } + + public static function unprotectArray($array, $is_tag = false) + { + return class_exists('RegularLabs\Library\Protect') && RL_Protect::unprotectArray($array, $is_tag); + } + + public static function unprotectForm(&$string, $tags = []) + { + class_exists('RegularLabs\Library\Protect') && RL_Protect::unprotectForm($string, $tags); + } + + public static function removeInlineComments(&$string, $name) + { + class_exists('RegularLabs\Library\Protect') && RL_Protect::removeInlineComments($string, $name); + } + + public static function removePluginTags(&$string, $tags, $character_start = '{', $character_end = '{', $keep_content = true) + { + class_exists('RegularLabs\Library\Protect') && RL_Protect::removePluginTags($string, $tags, $character_start, $character_end, $keep_content); + } + + public static function removeFromHtmlTagContent(&$string, $tags, $include_closing_tags = true, $html_tags = ['title']) + { + class_exists('RegularLabs\Library\Protect') && RL_Protect::removeFromHtmlTagContent($string, $tags, $include_closing_tags, $html_tags); + } + + public static function removeFromHtmlTagAttributes(&$string, $tags, $attributes = 'ALL', $include_closing_tags = true) + { + class_exists('RegularLabs\Library\Protect') && RL_Protect::removeFromHtmlTagAttributes($string, $tags, $attributes, $include_closing_tags); + } + + public static function articlePassesSecurity(&$article, $securtiy_levels = []) + { + return class_exists('RegularLabs\Library\Protect') && RL_Protect::articlePassesSecurity($article, $securtiy_levels); + } + + public static function isJoomla3() + { + return true; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/search.php b/deployed/regularlabs/libraries/regularlabs/helpers/search.php new file mode 100644 index 00000000..40346bb9 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/search.php @@ -0,0 +1,290 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * BASE ON JOOMLA CORE FILE: + * /components/com_search/models/search.php + */ + +/** + * @package Joomla.Site + * @subpackage com_search + * + * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; +use Joomla\CMS\MVC\Model\BaseDatabaseModel as JModel; +use Joomla\CMS\Pagination\Pagination as JPagination; +use Joomla\CMS\Plugin\PluginHelper as JPluginHelper; + +/** + * Search Component Search Model + * + * @since 1.5 + */ +class SearchModelSearch extends JModel +{ + /** + * Search data array + * + * @var array + */ + protected $_data = null; + + /** + * Search total + * + * @var integer + */ + protected $_total = null; + + /** + * Search areas + * + * @var integer + */ + protected $_areas = null; + + /** + * Pagination object + * + * @var object + */ + protected $_pagination = null; + + /** + * Constructor + * + * @since 1.5 + */ + public function __construct() + { + parent::__construct(); + + // Get configuration + $app = JFactory::getApplication(); + $config = JFactory::getConfig(); + + // Get the pagination request variables + $this->setState('limit', $app->getUserStateFromRequest('com_search.limit', 'limit', $config->get('list_limit'), 'uint')); + $this->setState('limitstart', $app->input->get('limitstart', 0, 'uint')); + + // Get parameters. + $params = $app->getParams(); + + if ($params->get('searchphrase') == 1) + { + $searchphrase = 'any'; + } + elseif ($params->get('searchphrase') == 2) + { + $searchphrase = 'exact'; + } + else + { + $searchphrase = 'all'; + } + + // Set the search parameters + $keyword = urldecode($app->input->getString('searchword')); + $match = $app->input->get('searchphrase', $searchphrase, 'word'); + $ordering = $app->input->get('ordering', $params->get('ordering', 'newest'), 'word'); + $this->setSearch($keyword, $match, $ordering); + + // Set the search areas + $areas = $app->input->get('areas', null, 'array'); + $this->setAreas($areas); + } + + /** + * Method to set the search parameters + * + * @param string $keyword string search string + * @param string $match matching option, exact|any|all + * @param string $ordering option, newest|oldest|popular|alpha|category + * + * @return void + * + * @access public + */ + public function setSearch($keyword, $match = 'all', $ordering = 'newest') + { + if (isset($keyword)) + { + $this->setState('origkeyword', $keyword); + + if ($match !== 'exact') + { + $keyword = preg_replace('#\xE3\x80\x80#s', ' ', $keyword); + } + + $this->setState('keyword', $keyword); + } + + if (isset($match)) + { + $this->setState('match', $match); + } + + if (isset($ordering)) + { + $this->setState('ordering', $ordering); + } + } + + /** + * Method to get weblink item data for the category + * + * @access public + * @return array + */ + public function getData() + { + // Lets load the content if it doesn't already exist + if (empty($this->_data)) + { + $areas = $this->getAreas(); + + JPluginHelper::importPlugin('search'); + $dispatcher = JEventDispatcher::getInstance(); + $results = $dispatcher->trigger('onContentSearch', [ + $this->getState('keyword'), + $this->getState('match'), + $this->getState('ordering'), + $areas['active'], + ] + ); + + $rows = []; + + foreach ($results as $result) + { + $rows = array_merge((array) $rows, (array) $result); + } + + $this->_total = count($rows); + + if ($this->getState('limit') > 0) + { + $this->_data = array_splice($rows, $this->getState('limitstart'), $this->getState('limit')); + } + else + { + $this->_data = $rows; + } + + /* >>> ADDED: Run content plugins over results */ + $params = JFactory::getApplication()->getParams('com_content'); + $params->set('rl_search', 1); + foreach ($this->_data as $item) + { + if (empty($item->text)) + { + continue; + } + + $dispatcher->trigger('onContentPrepare', ['com_search.search.article', &$item, &$params, 0]); + + if (empty($item->title)) + { + continue; + } + + // strip html tags from title + $item->title = strip_tags($item->title); + } + /* <<< */ + } + + return $this->_data; + } + + /** + * Method to get the total number of weblink items for the category + * + * @access public + * + * @return integer + */ + public function getTotal() + { + return $this->_total; + } + + /** + * Method to set the search areas + * + * @param array $active areas + * @param array $search areas + * + * @return void + * + * @access public + */ + public function setAreas($active = [], $search = []) + { + $this->_areas['active'] = $active; + $this->_areas['search'] = $search; + } + + /** + * Method to get a pagination object of the weblink items for the category + * + * @access public + * @return integer + */ + public function getPagination() + { + // Lets load the content if it doesn't already exist + if (empty($this->_pagination)) + { + $this->_pagination = new JPagination($this->getTotal(), $this->getState('limitstart'), $this->getState('limit')); + } + + return $this->_pagination; + } + + /** + * Method to get the search areas + * + * @return int + * + * @since 1.5 + */ + public function getAreas() + { + // Load the Category data + if (empty($this->_areas['search'])) + { + $areas = []; + + JPluginHelper::importPlugin('search'); + $dispatcher = JEventDispatcher::getInstance(); + $searchareas = $dispatcher->trigger('onContentSearchAreas'); + + foreach ($searchareas as $area) + { + if (is_array($area)) + { + $areas = array_merge($areas, $area); + } + } + + $this->_areas['search'] = $areas; + } + + return $this->_areas; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/string.php b/deployed/regularlabs/libraries/regularlabs/helpers/string.php new file mode 100644 index 00000000..66f483c6 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/string.php @@ -0,0 +1,20 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +jimport('joomla.string.string'); + +abstract class RLString extends JString +{ +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/tags.php b/deployed/regularlabs/libraries/regularlabs/helpers/tags.php new file mode 100644 index 00000000..34d7741f --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/tags.php @@ -0,0 +1,199 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use RegularLabs\Library\Html as RL_Html; +use RegularLabs\Library\PluginTag as RL_PluginTag; +use RegularLabs\Library\RegEx as RL_RegEx; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +class RLTags +{ + static $protected_characters = [ + '=' => '[[:EQUAL:]]', + '"' => '[[:QUOTE:]]', + ',' => '[[:COMMA:]]', + '|' => '[[:BAR:]]', + ':' => '[[:COLON:]]', + ]; + + public static function getValuesFromString($string = '', $main_key = 'title', $known_boolean_keys = [], $keep_escaped = [',']) + { + return RL_PluginTag::getAttributesFromString($string, $main_key, $known_boolean_keys, $keep_escaped); + } + + public static function protectSpecialChars(&$string) + { + RL_PluginTag::protectSpecialChars($string); + } + + public static function unprotectSpecialChars(&$string, $keep_escaped_chars = []) + { + RL_PluginTag::unprotectSpecialChars($string, $keep_escaped_chars); + } + + public static function replaceKeyAliases(&$values, $key_aliases = [], $handle_plurals = false) + { + RL_PluginTag::replaceKeyAliases($values, $key_aliases, $handle_plurals); + } + + public static function convertOldSyntax(&$values, $known_boolean_keys = [], $extra_key = 'class') + { + RL_PluginTag::convertOldSyntax($values, $known_boolean_keys, $extra_key); + } + + public static function getRegexSpaces($modifier = '+') + { + return RL_PluginTag::getRegexSpaces($modifier); + } + + public static function getRegexInsideTag() + { + return RL_PluginTag::getRegexInsideTag(); + } + + public static function getRegexSurroundingTagPre($elements = ['p', 'span']) + { + return RL_PluginTag::getRegexSurroundingTagPre($elements); + } + + public static function getRegexSurroundingTagPost($elements = ['p', 'span']) + { + return RL_PluginTag::getRegexSurroundingTagPost($elements); + } + + public static function getRegexTags($tags, $include_no_attributes = true, $include_ending = true, $required_attributes = []) + { + return RL_PluginTag::getRegexTags($tags, $include_no_attributes, $include_ending, $required_attributes); + } + + public static function fixBrokenHtmlTags($string) + { + return RL_Html::fix($string); + } + + public static function cleanSurroundingTags($tags, $elements = ['p', 'span']) + { + return RL_Html::cleanSurroundingTags($tags, $elements); + } + + public static function fixSurroundingTags($tags) + { + return RL_Html::fixArray($tags); + } + + public static function removeEmptyHtmlTagPairs($string, $elements = ['p', 'span']) + { + return RL_Html::removeEmptyTagPairs($string, $elements); + } + + public static function getDivTags($start_tag = '', $end_tag = '', $tag_start = '{', $tag_end = '}') + { + $tag_start = RL_RegEx::unquote($tag_start); + $tag_end = RL_RegEx::unquote($tag_end); + + return RL_PluginTag::getDivTags($start_tag, $end_tag, $tag_start, $tag_end); + } + + public static function getTagValues($string = '', $keys = ['title'], $separator = '|', $equal = '=', $limit = 0) + { + return RL_PluginTag::getAttributesFromStringOld($string, $keys, $separator, $equal, $limit); + } + + /* @Deprecated */ + + public static function setSurroundingTags($pre, $post, $tags = 0) + { + if ($tags == 0) + { + // tags that have a matching ending tag + $tags = [ + 'div', 'p', 'span', 'pre', 'a', + 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', + 'strong', 'b', 'em', 'i', 'u', 'big', 'small', 'font', + // html 5 stuff + 'header', 'nav', 'section', 'article', 'aside', 'footer', + 'figure', 'figcaption', 'details', 'summary', 'mark', 'time', + ]; + } + + $a = explode('<', $pre); + $b = explode(' $a_tag) + { + $a[$i] = '<' . trim($a_tag); + $a_tags[$i] = RL_RegEx::replace('^([a-z0-9]+).*$', '\1', trim($a_tag)); + } + + $b_tags = $b; + + foreach ($b_tags as $i => $b_tag) + { + $b[$i] = ' $b_tag) + { + if (empty($b_tag) || ! in_array($b_tag, $tags)) + { + continue; + } + + foreach ($a_tags as $j => $a_tag) + { + if ($b_tag != $a_tag) + { + continue; + } + + $a_tags[$i] = ''; + $b[$i] = trim(RL_RegEx::replace('^', '', $b[$i])); + $a[$j] = trim(RL_RegEx::replace('^<' . $a_tag . '.*?>', '', $a[$j])); + break; + } + } + + foreach ($a_tags as $i => $tag) + { + if (empty($tag) || ! in_array($tag, $tags)) + { + continue; + } + + array_unshift($b, trim($a[$i])); + $a[$i] = ''; + } + + $a = array_reverse($a); + list($pre, $post) = [implode('', $a), implode('', $b)]; + + return [trim($pre), trim($post)]; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/text.php b/deployed/regularlabs/libraries/regularlabs/helpers/text.php new file mode 100644 index 00000000..57cf1670 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/text.php @@ -0,0 +1,195 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use RegularLabs\Library\Alias as RL_Alias; +use RegularLabs\Library\ArrayHelper as RL_Array; +use RegularLabs\Library\Date as RL_Date; +use RegularLabs\Library\Form as RL_Form; +use RegularLabs\Library\Html as RL_Html; +use RegularLabs\Library\HtmlTag as RL_HtmlTag; +use RegularLabs\Library\PluginTag as RL_PluginTag; +use RegularLabs\Library\RegEx as RL_RegEx; +use RegularLabs\Library\StringHelper as RL_String; +use RegularLabs\Library\Title as RL_Title; +use RegularLabs\Library\Uri as RL_Uri; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +class RLText +{ + /* Date functions */ + + public static function fixDate(&$date) + { + $date = RL_Date::fix($date); + } + + public static function fixDateOffset(&$date) + { + RL_Date::applyTimezone($date); + } + + public static function dateToDateFormat($dateFormat) + { + return RL_Date::strftimeToDateFormat($dateFormat); + } + + public static function dateToStrftimeFormat($dateFormat) + { + return RL_Date::dateToStrftimeFormat($dateFormat); + } + + /* String functions */ + + public static function html_entity_decoder($string, $quote_style = ENT_QUOTES, $charset = 'UTF-8') + { + return RL_String::html_entity_decoder($string, $quote_style, $charset); + } + + public static function stringContains($haystacks, $needles) + { + return RL_String::contains($haystacks, $needles); + } + + public static function is_alphanumeric($string) + { + return RL_String::is_alphanumeric($string); + } + + public static function splitString($string, $delimiters = [], $max_length = 10000, $maximize_parts = true) + { + return RL_String::split($string, $delimiters, $max_length, $maximize_parts); + } + + public static function strReplaceOnce($search, $replace, $string) + { + return RL_String::replaceOnce($search, $replace, $string); + } + + /* Array functions */ + + public static function toArray($data, $separator = '') + { + return RL_Array::toArray($data, $separator); + } + + public static function createArray($data, $separator = ',') + { + return RL_Array::toArray($data, $separator, true); + } + + /* RegEx functions */ + + public static function regexReplace($pattern, $replacement, $string) + { + return RL_RegEx::replace($pattern, $replacement, $string); + } + + public static function pregQuote($string = '', $delimiter = '#') + { + return RL_RegEx::quote($string, $delimiter); + } + + public static function pregQuoteArray($array = [], $delimiter = '#') + { + return RL_RegEx::quoteArray($array, $delimiter); + } + + /* Title functions */ + + public static function cleanTitle($string, $strip_tags = false, $strip_spaces = true) + { + return RL_Title::clean($string, $strip_tags, $strip_spaces); + } + + public static function createUrlMatches($titles = []) + { + return RL_Title::getUrlMatches($titles); + } + + /* Alias functions */ + + public static function createAlias($string) + { + return RL_Alias::get($string); + } + + /* Uri functions */ + + public static function getURI($hash = '') + { + return RL_Uri::get($hash); + } + + /* Plugin Tag functions */ + + public static function getTagRegex($tags, $include_no_attributes = true, $include_ending = true, $required_attributes = []) + { + return RL_PluginTag::getRegexTags($tags, $include_no_attributes, $include_ending, $required_attributes); + } + + /* HTML functions */ + public static function getBody($html) + { + return RL_Html::getBody($html); + } + + public static function getContentContainingSearches($string, $start_searches = [], $end_searches = [], $start_offset = 1000, $end_offset = null) + { + return RL_Html::getContentContainingSearches($string, $start_searches, $end_searches, $start_offset, $end_offset); + } + + public static function convertWysiwygToPlainText($string) + { + return RL_Html::convertWysiwygToPlainText($string); + } + + public static function combinePTags(&$string) + { + RL_Html::combinePTags($string); + } + + /* HTML Tag functions */ + + public static function combineTags($tag1, $tag2) + { + return RL_HtmlTag::combine($tag1, $tag2); + } + + public static function getAttribute($key, $string) + { + return RL_HtmlTag::getAttributeValue($key, $string); + } + + public static function getAttributes($string) + { + return RL_HtmlTag::getAttributes($string); + } + + public static function combineAttributes($string1, $string2) + { + return RL_HtmlTag::combineAttributes($string1, $string2); + } + + /* Form functions */ + + public static function prepareSelectItem($string, $published = 1, $type = '', $remove_first = 0) + { + return RL_Form::prepareSelectItem($string, $published, $type, $remove_first); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/helpers/versions.php b/deployed/regularlabs/libraries/regularlabs/helpers/versions.php new file mode 100644 index 00000000..d0384891 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/helpers/versions.php @@ -0,0 +1,44 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* @DEPRECATED */ + +defined('_JEXEC') or die; + +use RegularLabs\Library\Version as RL_Version; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +class RLVersions +{ + public static function getXMLVersion($alias, $urlformat = false, $type = 'component', $folder = 'system') + { + return ! class_exists('RegularLabs\Library\Version') ? '' : RL_Version::get($alias, $type, $folder); + } + + public static function getPluginXMLVersion($alias, $folder = 'system') + { + return ! class_exists('RegularLabs\Library\Version') ? '' : RL_Version::getPluginVersion($alias, $folder); + } + + public static function render($alias) + { + return ! class_exists('RegularLabs\Library\Version') ? '' : RL_Version::getMessage($alias); + } + + public static function getFooter($name, $copyright = 1) + { + return ! class_exists('RegularLabs\Library\Version') ? '' : RL_Version::getFooter($name, $copyright); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/regularlabs.xml b/deployed/regularlabs/libraries/regularlabs/regularlabs.xml new file mode 100644 index 00000000..9e14f862 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/regularlabs.xml @@ -0,0 +1,33 @@ + + + Regular Labs Library + regularlabs + + 18.12.3953 + December 2018 + Regular Labs (Peter van Westen) + info@regularlabs.com + https://www.regularlabs.com + Copyright © 2018 Regular Labs - All Rights Reserved + http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + + script.install.php + + + vendor + src + autoload.php + regularlabs.xml + fields + helpers + script.install.helper.php + + + + css + fonts + images + js + less + + diff --git a/deployed/regularlabs/libraries/regularlabs/script.install.helper.php b/deployed/regularlabs/libraries/regularlabs/script.install.helper.php new file mode 100644 index 00000000..084b4966 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/script.install.helper.php @@ -0,0 +1,878 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +class RegularLabsInstallerScriptHelper +{ + public $name = ''; + public $alias = ''; + public $extname = ''; + public $extension_type = ''; + public $plugin_folder = 'system'; + public $module_position = 'status'; + public $client_id = 1; + public $install_type = 'install'; + public $show_message = true; + public $db = null; + public $softbreak = null; + public $installed_version = ''; + + public function __construct(&$params) + { + $this->extname = $this->extname ?: $this->alias; + $this->db = JFactory::getDbo(); + } + + public function preflight($route, JAdapterInstance $adapter) + { + if ( ! in_array($route, ['install', 'update'])) + { + return true; + } + + JFactory::getLanguage()->load('plg_system_regularlabsinstaller', JPATH_PLUGINS . '/system/regularlabsinstaller'); + + $this->installed_version = $this->getVersion($this->getInstalledXMLFile()); + + if ($this->show_message && $this->isInstalled()) + { + $this->install_type = 'update'; + } + + if ($this->onBeforeInstall($route) === false) + { + return false; + } + + return true; + } + + public function postflight($route, JAdapterInstance $adapter) + { + $this->removeGlobalLanguageFiles(); + $this->removeUnusedLanguageFiles(); + + JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); + + if ( ! in_array($route, ['install', 'update'])) + { + return true; + } + + $this->fixExtensionNames(); + $this->updateUpdateSites(); + $this->removeAdminCache(); + + if ($this->onAfterInstall($route) === false) + { + return false; + } + + if ($route == 'install') + { + $this->publishExtension(); + } + + if ($this->show_message) + { + $this->addInstalledMessage(); + } + + JFactory::getCache()->clean('com_plugins'); + JFactory::getCache()->clean('_system'); + + return true; + } + + public function isInstalled() + { + if ( ! is_file($this->getInstalledXMLFile())) + { + return false; + } + + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('extension_id')) + ->from('#__extensions') + ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); + $this->db->setQuery($query, 0, 1); + $result = $this->db->loadResult(); + + return empty($result) ? false : true; + } + + public function getMainFolder() + { + switch ($this->extension_type) + { + case 'plugin' : + return JPATH_PLUGINS . '/' . $this->plugin_folder . '/' . $this->extname; + + case 'component' : + return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; + + case 'module' : + return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; + + case 'library' : + return JPATH_SITE . '/libraries/' . $this->extname; + } + } + + public function getInstalledXMLFile() + { + return $this->getXMLFile($this->getMainFolder()); + } + + public function getCurrentXMLFile() + { + return $this->getXMLFile(__DIR__); + } + + public function getXMLFile($folder) + { + switch ($this->extension_type) + { + case 'module' : + return $folder . '/mod_' . $this->extname . '.xml'; + + default : + return $folder . '/' . $this->extname . '.xml'; + } + } + + public function uninstallExtension($extname, $type = 'plugin', $folder = 'system', $show_message = true) + { + if (empty($extname)) + { + return; + } + + $folders = []; + + switch ($type) + { + case 'plugin'; + $folders[] = JPATH_PLUGINS . '/' . $folder . '/' . $extname; + break; + + case 'component': + $folders[] = JPATH_ADMINISTRATOR . '/components/com_' . $extname; + $folders[] = JPATH_SITE . '/components/com_' . $extname; + break; + + case 'module': + $folders[] = JPATH_ADMINISTRATOR . '/modules/mod_' . $extname; + $folders[] = JPATH_SITE . '/modules/mod_' . $extname; + break; + } + + if ( ! $this->foldersExist($folders)) + { + return; + } + + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('extension_id')) + ->from('#__extensions') + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName($type, $extname))) + ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($type)); + + if ($type == 'plugin') + { + $query->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($folder)); + } + + $this->db->setQuery($query); + $ids = $this->db->loadColumn(); + + if (empty($ids)) + { + foreach ($folders as $folder) + { + JFactory::getApplication()->enqueueMessage('2. Deleting: ' . $folder, 'notice'); + JFolder::delete($folder); + } + + return; + } + + $ignore_ids = JFactory::getApplication()->getUserState('rl_ignore_uninstall_ids', []); + + if (JFactory::getApplication()->input->get('option') == 'com_installer' && JFactory::getApplication()->input->get('task') == 'remove') + { + // Don't attempt to uninstall extensions that are already selected to get uninstalled by them selves + $ignore_ids = array_merge($ignore_ids, JFactory::getApplication()->input->get('cid', [], 'array')); + JFactory::getApplication()->input->set('cid', array_merge($ignore_ids, $ids)); + } + + $ids = array_diff($ids, $ignore_ids); + + if (empty($ids)) + { + return; + } + + $ignore_ids = array_merge($ignore_ids, $ids); + JFactory::getApplication()->setUserState('rl_ignore_uninstall_ids', $ignore_ids); + + foreach ($ids as $id) + { + $tmpInstaller = new JInstaller; + $tmpInstaller->uninstall($type, $id); + } + + if ($show_message) + { + JFactory::getApplication()->enqueueMessage( + JText::sprintf( + 'COM_INSTALLER_UNINSTALL_SUCCESS', + JText::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($type)) + ) + ); + } + } + + public function foldersExist($folders = []) + { + foreach ($folders as $folder) + { + if (is_dir($folder)) + { + return true; + } + } + + return false; + } + + public function uninstallPlugin($extname, $folder = 'system', $show_message = true) + { + $this->uninstallExtension($extname, 'plugin', $folder, $show_message); + } + + public function uninstallComponent($extname, $show_message = true) + { + $this->uninstallExtension($extname, 'component', null, $show_message); + } + + public function uninstallModule($extname, $show_message = true) + { + $this->uninstallExtension($extname, 'module', null, $show_message); + } + + public function publishExtension() + { + switch ($this->extension_type) + { + case 'plugin' : + $this->publishPlugin(); + + case 'module' : + $this->publishModule(); + } + } + + public function publishPlugin() + { + $query = $this->db->getQuery(true) + ->update('#__extensions') + ->set($this->db->quoteName('enabled') . ' = 1') + ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) + ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); + $this->db->setQuery($query); + $this->db->execute(); + } + + public function publishModule() + { + // Get module id + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('id')) + ->from('#__modules') + ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) + ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + if ( ! $id) + { + return; + } + + // check if module is already in the modules_menu table (meaning is is already saved) + $query->clear() + ->select($this->db->quoteName('moduleid')) + ->from('#__modules_menu') + ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); + $this->db->setQuery($query, 0, 1); + $exists = $this->db->loadResult(); + + if ($exists) + { + return; + } + + // Get highest ordering number in position + $query->clear() + ->select($this->db->quoteName('ordering')) + ->from('#__modules') + ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) + ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) + ->order('ordering DESC'); + $this->db->setQuery($query, 0, 1); + $ordering = $this->db->loadResult(); + $ordering++; + + // publish module and set ordering number + $query->clear() + ->update('#__modules') + ->set($this->db->quoteName('published') . ' = 1') + ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) + ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) + ->where($this->db->quoteName('id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + + // add module to the modules_menu table + $query->clear() + ->insert('#__modules_menu') + ->columns([$this->db->quoteName('moduleid'), $this->db->quoteName('menuid')]) + ->values((int) $id . ', 0'); + $this->db->setQuery($query); + $this->db->execute(); + } + + public function addInstalledMessage() + { + JFactory::getApplication()->enqueueMessage( + JText::sprintf( + JText::_($this->install_type == 'update' ? 'RLI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'RLI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), + '' . JText::_($this->name) . '', + '' . $this->getVersion() . '', + $this->getFullType() + ) + ); + } + + public function getPrefix() + { + switch ($this->extension_type) + { + case 'plugin'; + return JText::_('plg_' . strtolower($this->plugin_folder)); + + case 'component': + return JText::_('com'); + + case 'module': + return JText::_('mod'); + + case 'library': + return JText::_('lib'); + + default: + return $this->extension_type; + } + } + + public function getElementName($type = null, $extname = null) + { + $type = is_null($type) ? $this->extension_type : $type; + $extname = is_null($extname) ? $this->extname : $extname; + + switch ($type) + { + case 'component' : + return 'com_' . $extname; + + case 'module' : + return 'mod_' . $extname; + + case 'plugin' : + default: + return $extname; + } + } + + public function getFullType() + { + return JText::_('RLI_' . strtoupper($this->getPrefix())); + } + + public function getVersion($file = '') + { + $file = $file ?: $this->getCurrentXMLFile(); + + if ( ! is_file($file)) + { + return ''; + } + + $xml = JApplicationHelper::parseXMLInstallFile($file); + + if ( ! $xml || ! isset($xml['version'])) + { + return ''; + } + + return $xml['version']; + } + + public function isNewer() + { + if ( ! $this->installed_version) + { + return true; + } + + $package_version = $this->getVersion(); + + return version_compare($this->installed_version, $package_version, '<='); + } + + public function canInstall() + { + // The extension is not installed yet + if ( ! $this->installed_version) + { + return true; + } + + // The free version is installed. So any version is ok to install + if (strpos($this->installed_version, 'PRO') === false) + { + return true; + } + + // Current package is a pro version, so all good + if (strpos($this->getVersion(), 'PRO') !== false) + { + return true; + } + + JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); + + JFactory::getApplication()->enqueueMessage(JText::_('RLI_ERROR_PRO_TO_FREE'), 'error'); + + JFactory::getApplication()->enqueueMessage( + html_entity_decode( + JText::sprintf( + 'RLI_ERROR_UNINSTALL_FIRST', + '', + '', + JText::_($this->name) + ) + ), 'error' + ); + + return false; + } + + /* + * Fixes incorrectly formed versions because of issues in old packager + */ + public function fixFileVersions($file) + { + if (is_array($file)) + { + foreach ($file as $f) + { + self::fixFileVersions($f); + } + + return; + } + + if ( ! is_string($file) || ! is_file($file)) + { + return; + } + + $contents = file_get_contents($file); + + if ( + strpos($contents, 'FREEFREE') === false + && strpos($contents, 'FREEPRO') === false + && strpos($contents, 'PROFREE') === false + && strpos($contents, 'PROPRO') === false + ) + { + return; + } + + $contents = str_replace( + ['FREEFREE', 'FREEPRO', 'PROFREE', 'PROPRO'], + ['FREE', 'PRO', 'FREE', 'PRO'], + $contents + ); + + JFile::write($file, $contents); + } + + public function onBeforeInstall($route) + { + if ( ! $this->canInstall()) + { + return false; + } + + return true; + } + + public function onAfterInstall($route) + { + } + + public function delete($files = []) + { + foreach ($files as $file) + { + if (is_dir($file)) + { + JFolder::delete($file); + } + + if (is_file($file)) + { + JFile::delete($file); + } + } + } + + public function fixAssetsRules() + { + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('rules')) + ->from('#__assets') + ->where($this->db->quoteName('title') . ' = ' . $this->db->quote('com_' . $this->extname)); + $this->db->setQuery($query, 0, 1); + $rules = $this->db->loadResult(); + + $rules = json_decode($rules); + + if(empty($rules)) { + return; + } + + foreach($rules as $key => $value) { + if(!empty($value)) { + continue; + } + + unset($rules->$key); + } + + $rules = json_encode($rules); + + + $query = $this->db->getQuery(true) + ->update($this->db->quoteName('#__assets')) + ->set($this->db->quoteName('rules') . ' = ' . $this->db->quote($rules)) + ->where($this->db->quoteName('title') . ' = ' . $this->db->quote('com_' . $this->extname)); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function fixExtensionNames() + { + switch ($this->extension_type) + { + case 'module' : + $this->fixModuleNames(); + } + } + + private function fixModuleNames() + { + // Get module id + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('id')) + ->from('#__modules') + ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) + ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); + $this->db->setQuery($query, 0, 1); + $module_id = $this->db->loadResult(); + + if (empty($module_id)) + { + return; + } + + $title = 'Regular Labs - ' . JText::_($this->name); + + $query->clear() + ->update('#__modules') + ->set($this->db->quoteName('title') . ' = ' . $this->db->quote($title)) + ->where($this->db->quoteName('id') . ' = ' . (int) $module_id) + ->where($this->db->quoteName('title') . ' LIKE ' . $this->db->quote('NoNumber%')); + $this->db->setQuery($query); + $this->db->execute(); + + // Fix module assets + + // Get asset id + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('id')) + ->from('#__assets') + ->where($this->db->quoteName('name') . ' = ' . $this->db->quote('com_modules.module.' . (int) $module_id)) + ->where($this->db->quoteName('title') . ' LIKE ' . $this->db->quote('NoNumber%')); + $this->db->setQuery($query, 0, 1); + $asset_id = $this->db->loadResult(); + + if (empty($asset_id)) + { + return; + } + + $query->clear() + ->update('#__assets') + ->set($this->db->quoteName('title') . ' = ' . $this->db->quote($title)) + ->where($this->db->quoteName('id') . ' = ' . (int) $asset_id); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function updateUpdateSites() + { + $this->removeOldUpdateSites(); + $this->updateNamesInUpdateSites(); + $this->updateHttptoHttpsInUpdateSites(); + $this->removeDuplicateUpdateSite(); + $this->updateDownloadKey(); + } + + private function removeOldUpdateSites() + { + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('nonumber.nl%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + if ( ! $id) + { + return; + } + + $query->clear() + ->delete('#__update_sites') + ->where($this->db->quoteName('update_site_id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + + $query->clear() + ->delete('#__update_sites_extensions') + ->where($this->db->quoteName('update_site_id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function updateNamesInUpdateSites() + { + $name = JText::_($this->name); + if ($this->alias != 'extensionmanager') + { + $name = 'Regular Labs - ' . $name; + } + + $query = $this->db->getQuery(true) + ->update('#__update_sites') + ->set($this->db->quoteName('name') . ' = ' . $this->db->quote($name)) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function updateHttptoHttpsInUpdateSites() + { + $query = $this->db->getQuery(true) + ->update('#__update_sites') + ->set($this->db->quoteName('location') . ' = REPLACE(' + . $this->db->quoteName('location') . ', ' + . $this->db->quote('http://') . ', ' + . $this->db->quote('https://') + . ')') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('http://download.regularlabs.com%')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function removeDuplicateUpdateSite() + { + // First check to see if there is a pro entry + + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')) + ->where($this->db->quoteName('location') . ' NOT LIKE ' . $this->db->quote('%pro=1%')); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + // Otherwise just get the first match + if ( ! $id) + { + $query->clear() + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + // Remove pro=1 from the found update site + $query->clear() + ->update('#__update_sites') + ->set($this->db->quoteName('location') + . ' = replace(' . $this->db->quoteName('location') . ', ' . $this->db->quote('&pro=1') . ', ' . $this->db->quote('') . ')') + ->where($this->db->quoteName('update_site_id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + } + + if ( ! $id) + { + return; + } + + $query->clear() + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')) + ->where($this->db->quoteName('update_site_id') . ' != ' . $id); + $this->db->setQuery($query); + $ids = $this->db->loadColumn(); + + if (empty($ids)) + { + return; + } + + $query->clear() + ->delete('#__update_sites') + ->where($this->db->quoteName('update_site_id') . ' IN (' . implode(',', $ids) . ')'); + $this->db->setQuery($query); + $this->db->execute(); + + $query->clear() + ->delete('#__update_sites_extensions') + ->where($this->db->quoteName('update_site_id') . ' IN (' . implode(',', $ids) . ')'); + $this->db->setQuery($query); + $this->db->execute(); + } + + // Save the download key from the Regular Labs Extension Manager config to the update sites + private function updateDownloadKey() + { + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('params')) + ->from('#__extensions') + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote('com_regularlabsmanager')); + $this->db->setQuery($query); + $params = $this->db->loadResult(); + + if ( ! $params) + { + return; + } + + $params = json_decode($params); + + if ( ! isset($params->key)) + { + return; + } + + // Add the key on all regularlabs.com urls + $query->clear() + ->update('#__update_sites') + ->set($this->db->quoteName('extra_query') . ' = ' . $this->db->quote('k=' . $params->key)) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function removeAdminCache() + { + $this->delete([JPATH_ADMINISTRATOR . '/cache/regularlabs']); + $this->delete([JPATH_ADMINISTRATOR . '/cache/nonumber']); + } + + private function removeGlobalLanguageFiles() + { + if ($this->extension_type == 'library') + { + return; + } + + $language_files = JFolder::files(JPATH_ADMINISTRATOR . '/language', '\.' . $this->getPrefix() . '_' . $this->extname . '\.', true, true); + + // Remove override files + foreach ($language_files as $i => $language_file) + { + if (strpos($language_file, '/overrides/') === false) + { + continue; + } + + unset($language_files[$i]); + } + + if (empty($language_files)) + { + return; + } + + JFile::delete($language_files); + } + + private function removeUnusedLanguageFiles() + { + if ($this->extension_type == 'library') + { + return; + } + + $installed_languages = array_merge( + JFolder::folders(JPATH_SITE . '/language'), + JFolder::folders(JPATH_ADMINISTRATOR . '/language') + ); + + $languages = array_diff( + JFolder::folders(__DIR__ . '/language'), + $installed_languages + ); + + $delete_languages = []; + + foreach ($languages as $language) + { + $delete_languages[] = $this->getMainFolder() . '/language/' . $language; + } + + if (empty($delete_languages)) + { + return; + } + + // Remove folders + $this->delete($delete_languages); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/script.install.php b/deployed/regularlabs/libraries/regularlabs/script.install.php new file mode 100644 index 00000000..64c9fcbc --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/script.install.php @@ -0,0 +1,36 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +if ( ! class_exists('RegularLabsInstallerScript')) +{ + require_once __DIR__ . '/script.install.helper.php'; + + class RegularLabsInstallerScript extends RegularLabsInstallerScriptHelper + { + public $name = 'Regular Labs Library'; + public $alias = 'regularlabs'; + public $extension_type = 'library'; + + public function onBeforeInstall($route) + { + if ( ! $this->isNewer()) + { + $this->softbreak = true; + + return false; + } + + return true; + } + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/src/ActionLogPlugin.php b/deployed/regularlabs/libraries/regularlabs/src/ActionLogPlugin.php new file mode 100644 index 00000000..b8cd858d --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/src/ActionLogPlugin.php @@ -0,0 +1,308 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Library; + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; +use Joomla\CMS\Language\Text as JText; +use Joomla\CMS\Plugin\CMSPlugin as JPlugin; +use RegularLabs\Library\ArrayHelper as RL_Array; +use RegularLabs\Library\Extension as RL_Extension; +use RegularLabs\Library\Log as RL_Log; +use RegularLabs\Library\Parameters as RL_Parameters; + +/** + * Class ActionLogPlugin + * @package RegularLabs\Library + */ +class ActionLogPlugin + extends JPlugin +{ + public $name = ''; + public $alias = ''; + public $option = ''; + public $items = []; + public $table = null; + public $events = []; + + static $ids = []; + + public function __construct(&$subject, array $config = []) + { + parent::__construct($subject, $config); + + Language::load('plg_actionlog_' . $this->alias); + + $config = RL_Parameters::getInstance()->getComponentParams($this->alias); + + $enable_actionlog = isset($config->enable_actionlog) ? $config->enable_actionlog : true; + $this->events = $enable_actionlog ? ['*'] : []; + + if ($enable_actionlog && ! empty($config->actionlog_events)) + { + $this->events = RL_Array::toArray($config->actionlog_events); + } + + $this->name = JText::_($this->name); + $this->option = $this->option ?: 'com_' . $this->alias; + } + + public function onContentAfterSave($context, $table, $isNew) + { + if (strpos($context, $this->option) === false) + { + return; + } + + $event = $isNew ? 'create' : 'update'; + + if ( ! RL_Array::find(['*', $event], $this->events)) + { + return; + } + + $item = $this->getItem($context); + + $title = isset($table->title) ? $table->title : (isset($table->name) ? $table->name : $table->id); + $item_url = str_replace('{id}', $table->id, $item->url); + + $message = [ + 'type' => $item->title, + 'id' => $table->id, + 'title' => $title, + 'itemlink' => $item_url, + ]; + + RL_Log::save($message, $context, $isNew); + } + + public function onContentAfterDelete($context, $table) + { + if (strpos($context, $this->option) === false) + { + return; + } + + if ( ! RL_Array::find(['*', 'delete'], $this->events)) + { + return; + } + + $item = $this->getItem($context); + + $title = isset($table->title) ? $table->title : (isset($table->name) ? $table->name : $table->id); + + $message = [ + 'type' => $item->title, + 'id' => $table->id, + 'title' => $title, + ]; + + RL_Log::delete($message, $context); + } + + public function onContentChangeState($context, $ids, $value) + { + if (strpos($context, $this->option) === false) + { + return; + } + + if ( ! RL_Array::find(['*', 'change_state'], $this->events)) + { + return; + } + + $item = $this->getItem($context); + + if ( ! $this->table) + { + if ( ! is_file($item->file)) + { + return; + } + + require_once $item->file; + + $this->table = (new $item->model)->getTable(); + } + + foreach ($ids as $id) + { + $this->table->load($id); + + $title = isset($this->table->title) ? $this->table->title : (isset($this->table->name) ? $this->table->name : $this->table->id); + $itemlink = str_replace('{id}', $this->table->id, $item->url); + + $message = [ + 'type' => $item->title, + 'id' => $id, + 'title' => $title, + 'itemlink' => $itemlink, + ]; + + RL_Log::changeState($message, $context, $value); + } + } + + public function onExtensionAfterSave($context, $table, $isNew) + { + self::onContentAfterSave($context, $table, $isNew); + } + + public function onExtensionAfterDelete($context, $table) + { + self::onContentAfterDelete($context, $table); + } + + public function onExtensionAfterInstall($installer, $eid) + { + // Prevent duplicate logs + if (in_array('install_' . $eid, self::$ids)) + { + return; + } + + $context = JFactory::getApplication()->input->get('option'); + + if (strpos($context, $this->option) === false) + { + return; + } + + if ( ! RL_Array::find(['*', 'install'], $this->events)) + { + return; + } + + $extension = RL_Extension::getById($eid); + + if (empty($extension->manifest_cache)) + { + return; + } + + $manifest = json_decode($extension->manifest_cache); + + if (empty($manifest->name)) + { + return; + } + + self::$ids[] = 'install_' . $eid; + + $message = [ + 'id' => $eid, + 'extension_name' => JText::_($manifest->name), + ]; + + RL_Log::install($message, 'com_regularlabsmanager', $manifest->type); + } + + public function onExtensionAfterUninstall($installer, $eid, $result) + { + // Prevent duplicate logs + if (in_array('uninstall_' . $eid, self::$ids)) + { + return; + } + + $context = JFactory::getApplication()->input->get('option'); + + if (strpos($context, $this->option) === false) + { + return; + } + + if ( ! RL_Array::find(['*', 'uninstall'], $this->events)) + { + return; + } + + if ($result === false) + { + return; + } + + $manifest = $installer->get('manifest'); + + if ($manifest === null) + { + return; + } + + self::$ids[] = 'uninstall_' . $eid; + + $message = [ + 'id' => $eid, + 'extension_name' => JText::_($manifest->name), + ]; + + RL_Log::uninstall($message, 'com_regularlabsmanager', $manifest->attributes()->type); + } + + private function getItem($context) + { + $item = $this->getItemData($context); + + $item->title = isset($item->title) + ? JText::_($item->title) + : $this->type . ' ' . JText::_('RL_ITEM'); + + if ( ! isset($item->file)) + { + $item->file = JPATH_ADMINISTRATOR . '/components/' . $this->option . '/models/' . $item->type . '.php'; + } + + if ( ! isset($item->model)) + { + $item->model = $this->alias . 'Model' . ucfirst($item->type); + } + + if ( ! isset($item->url)) + { + $item->url = 'index.php?option=' . $this->option . '&view=' . $item->type . '&layout=edit&id={id}'; + } + + return $item; + } + + private function getItemData($context) + { + $default = (object) [ + 'type' => 'item', + ]; + + $type = key($this->items) ?: 'item'; + + if (strpos($context, '.') !== false) + { + $parts = explode('.', $context); + $type = $parts[1]; + } + + if ( ! isset($this->items[$type])) + { + return $default; + } + + $item = $this->items[$type]; + + if ( ! isset($item->type)) + { + $item->type = $type; + } + + return $item; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/src/Alias.php b/deployed/regularlabs/libraries/regularlabs/src/Alias.php new file mode 100644 index 00000000..88c1d64e --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/src/Alias.php @@ -0,0 +1,113 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Library; + +defined('_JEXEC') or die; + +use Joomla\CMS\Application\ApplicationHelper as JApplicationHelper; +use Joomla\CMS\Factory as JFactory; + +/** + * Class Alias + * @package RegularLabs\Library + */ +class Alias +{ + /** + * Creates an alias from a string + * + * @param string $string + * + * @return string + */ + public static function get($string = '', $unicode = false) + { + if (empty($string)) + { + return ''; + } + + $string = StringHelper::removeHtml($string); + + if ($unicode || JFactory::getConfig()->get('unicodeslugs') == 1) + { + return self::stringURLUnicodeSlug($string); + } + + // Remove < > html entities + $string = str_replace(['<', '>'], '', $string); + + // Convert html entities + $string = StringHelper::html_entity_decoder($string); + + return JApplicationHelper::stringURLSafe($string); + } + + /** + * Creates a unicode alias from a string + * Based on stringURLUnicodeSlug method from the unicode slug plugin by infograf768 + * + * @param string $string + * + * @return string + */ + private static function stringURLUnicodeSlug($string = '') + { + if (empty($string)) + { + return ''; + } + + // Remove < > html entities + $string = str_replace(['<', '>'], '', $string); + + // Convert html entities + $string = StringHelper::html_entity_decoder($string); + + // Convert to lowercase + $string = StringHelper::strtolower($string); + + // remove html tags + $string = RegEx::replace(']*>', '', $string); + // remove comments tags + $string = RegEx::replace('<\!--.*?-->', '', $string); + + // Replace weird whitespace characters like (Â) with spaces + //$string = str_replace(array(chr(160), chr(194)), ' ', $string); + $string = str_replace("\xC2\xA0", ' ', $string); + $string = str_replace("\xE2\x80\xA8", ' ', $string); // ascii only + + // Replace double byte whitespaces by single byte (East Asian languages) + $string = str_replace("\xE3\x80\x80", ' ', $string); + + // Remove any '-' from the string as they will be used as concatenator. + // Would be great to let the spaces in but only Firefox is friendly with this + $string = str_replace('-', ' ', $string); + + // Replace forbidden characters by whitespaces + $string = RegEx::replace('[' . RegEx::quote(',:#$*"@+=;&.%()[]{}/\'\\|') . ']', "\x20", $string); + + // Delete all characters that should not take up any space, like: ? + $string = RegEx::replace('[' . RegEx::quote('?!¿¡') . ']', '', $string); + + // Trim white spaces at beginning and end of alias and make lowercase + $string = trim($string); + + // Remove any duplicate whitespace and replace whitespaces by hyphens + $string = RegEx::replace('\x20+', '-', $string); + + // Remove leading and trailing hyphens + $string = trim($string, '-'); + + return $string; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/src/Api/ConditionInterface.php b/deployed/regularlabs/libraries/regularlabs/src/Api/ConditionInterface.php new file mode 100644 index 00000000..ecfcb3f9 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/src/Api/ConditionInterface.php @@ -0,0 +1,23 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Library\Api; + +defined('_JEXEC') or die; + +/** + * Interface ConditionConditionInterface + * @package RegularLabs\Library\Api + */ +interface ConditionInterface +{ + public function pass(); +} diff --git a/deployed/regularlabs/libraries/regularlabs/src/ArrayHelper.php b/deployed/regularlabs/libraries/regularlabs/src/ArrayHelper.php new file mode 100644 index 00000000..81782dc6 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/src/ArrayHelper.php @@ -0,0 +1,210 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Library; + +defined('_JEXEC') or die; + +/** + * Class ArrayHelper + * @package RegularLabs\Library + */ +class ArrayHelper +{ + /** + * Convert data (string or object) to an array + * + * @param mixed $data + * @param string $separator + * @param bool $unique + * + * @return array + */ + public static function toArray($data, $separator = ',', $unique = false, $trim = true) + { + if (is_array($data)) + { + return $data; + } + + if (is_object($data)) + { + return (array) $data; + } + + if ($data == '') + { + return []; + } + + if ($separator == '') + { + return [$data]; + } + + $array = explode($separator, $data); + + if ($trim) + { + $array = self::trim($array); + } + + if ($unique) + { + $array = array_unique($array); + } + + return $array; + } + + /** + * Clean array by trimming values and removing empty/false values + * + * @param array $array + * + * @return array + */ + public static function clean($array) + { + if ( ! is_array($array)) + { + return $array; + } + + $array = self::trim($array); + $array = self::unique($array); + $array = self::removeEmpty($array); + + return $array; + } + + /** + * Removes empty values from the array + * + * @param array $array + * + * @return array + */ + public static function removeEmpty($array) + { + if ( ! is_array($array)) + { + return $array; + } + + foreach ($array as $key => &$value) + { + if ($key && ! is_numeric($key)) + { + continue; + } + + if ($value !== '') + { + continue; + } + + unset($array[$key]); + } + + return $array; + } + + /** + * Removes duplicate values from the array + * + * @param array $array + * + * @return array + */ + public static function unique($array) + { + if ( ! is_array($array)) + { + return $array; + } + + $values = []; + + foreach ($array as $key => $value) + { + if ( ! is_numeric($key)) + { + continue; + } + + if ( ! in_array($value, $values)) + { + $values[] = $value; + continue; + } + + unset($array[$key]); + } + + return $array; + } + + /** + * Clean array by trimming values + * + * @param array $array + * + * @return array + */ + public static function trim($array) + { + if ( ! is_array($array)) + { + return $array; + } + + foreach ($array as &$value) + { + if ( ! is_string($value)) + { + continue; + } + + $value = trim($value); + } + + return $array; + } + + /** + * Check if any of the given values is found in the array + * + * @param array $values + * @param array $array + * + * @return boolean + */ + public static function find($values, $array) + { + if ( ! is_array($array) || empty($array)) + { + return false; + } + + $values = self::toArray($values); + + foreach ($values as $value) + { + if (in_array($value, $array)) + { + return true; + } + } + + return false; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/src/Article.php b/deployed/regularlabs/libraries/regularlabs/src/Article.php new file mode 100644 index 00000000..1a54bff7 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/src/Article.php @@ -0,0 +1,228 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Library; + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; +use Joomla\Registry\Registry; + +jimport('joomla.filesystem.file'); + +/** + * Class Article + * @package RegularLabs\Library + */ +class Article +{ + static $articles = []; + static $splitter = '[[:SPLIT-ARTICLE:]]'; + + /** + * Method to get article data. + * + * @param integer $id The id of the article. + * + * @return object|boolean Menu item data object on success, boolean false + */ + public static function get($id = null, $get_unpublished = false) + { + $id = ! empty($id) ? $id : (int) self::getId(); + + if (isset(self::$articles[$id])) + { + return self::$articles[$id]; + } + + $db = JFactory::getDbo(); + $user = JFactory::getUser(); + + $query = $db->getQuery(true) + ->select( + [ + 'a.id', 'a.asset_id', 'a.title', 'a.alias', 'a.introtext', 'a.fulltext', + 'a.state', 'a.catid', 'a.created', 'a.created_by', 'a.created_by_alias', + // Use created if modified is 0 + 'CASE WHEN a.modified = ' . $db->quote($db->getNullDate()) . ' THEN a.created ELSE a.modified END as modified', + 'a.modified_by', 'a.checked_out', 'a.checked_out_time', 'a.publish_up', 'a.publish_down', + 'a.images', 'a.urls', 'a.attribs', 'a.version', 'a.ordering', + 'a.metakey', 'a.metadesc', 'a.access', 'a.hits', 'a.metadata', 'a.featured', 'a.language', 'a.xreference', + ] + ) + ->from($db->quoteName('#__content', 'a')) + ->where($db->quoteName('a.id') . ' = ' . (int) $id); + + // Join on category table. + $query->select([ + $db->quoteName('c.title', 'category_title'), + $db->quoteName('c.alias', 'category_alias'), + $db->quoteName('c.access', 'category_access'), + ]) + ->innerJoin($db->quoteName('#__categories', 'c') . ' ON ' . $db->quoteName('c.id') . ' = ' . $db->quoteName('a.catid')) + ->where($db->quoteName('c.published') . ' > 0'); + + // Join on user table. + $query->select($db->quoteName('u.name', 'author')) + ->join('LEFT', $db->quoteName('#__users', 'u') . ' ON ' . $db->quoteName('u.id') . ' = ' . $db->quoteName('a.created_by')); + + // Join over the categories to get parent category titles + $query->select([ + $db->quoteName('parent.title', 'parent_title'), + $db->quoteName('parent.id', 'parent_id'), + $db->quoteName('parent.path', 'parent_route'), + $db->quoteName('parent.alias', 'parent_alias'), + ]) + ->join('LEFT', $db->quoteName('#__categories', 'parent') . ' ON ' . $db->quoteName('parent.id') . ' = ' . $db->quoteName('c.parent_id')); + + // Join on voting table + $query->select([ + 'ROUND(v.rating_sum / v.rating_count, 0) AS rating', + $db->quoteName('v.rating_count', 'rating_count'), + ]) + ->join('LEFT', $db->quoteName('#__content_rating', 'v') . ' ON ' . $db->quoteName('v.content_id') . ' = ' . $db->quoteName('a.id')); + + if ( ! $get_unpublished + && ( ! $user->authorise('core.edit.state', 'com_content')) + && ( ! $user->authorise('core.edit', 'com_content')) + ) + { + // Filter by start and end dates. + $nullDate = $db->quote($db->getNullDate()); + $date = JFactory::getDate(); + + $nowDate = $db->quote($date->toSql()); + + $query->where($db->quoteName('a.state') . ' = 1') + ->where('(' . $db->quoteName('a.publish_up') . ' = ' . $nullDate . ' OR ' . $db->quoteName('a.publish_up') . ' <= ' . $nowDate . ')') + ->where('(' . $db->quoteName('a.publish_down') . ' = ' . $nullDate . ' OR ' . $db->quoteName('a.publish_down') . ' >= ' . $nowDate . ')'); + } + + $db->setQuery($query); + + $data = $db->loadObject(); + + if (empty($data)) + { + return false; + } + + // Convert parameter fields to objects. + $data->params = new Registry($data->attribs); + $data->metadata = new Registry($data->metadata); + + self::$articles[$id] = $data; + + return self::$articles[$id]; + } + + /** + * Gets the current article id based on url data + */ + public static function getId() + { + $input = JFactory::getApplication()->input; + + if ( ! $id = $input->getInt('id') + || ! (($input->get('option') == 'com_content' && $input->get('view') == 'article') + || ($input->get('option') == 'com_flexicontent' && $input->get('view') == 'item') + ) + ) + { + return false; + } + + return $id; + } + + /** + * Passes the different article parts through the given plugin method + * + * @param object $article + * @param string $context + * @param object $helper + * @param string $method + * @param array $params + * @param array $ignore + */ + public static function process(&$article, &$context, &$helper, $method, $params = [], $ignore = []) + { + self::processText('title', $article, $helper, $method, $params, $ignore); + self::processText('created_by_alias', $article, $helper, $method, $params, $ignore); + self::processText('description', $article, $helper, $method, $params, $ignore); + + // Don't replace in text fields in the category list view, as they won't get used anyway + if (Document::isCategoryList($context)) + { + return; + } + + // prevent fulltext from being messed with, when it is a json encoded string (Yootheme Pro templates do this for some weird f-ing reason) + if ( ! empty($article->fulltext) && substr($article->fulltext, 0, 6) == '\s*)*'; + + $string = implode($splitter, $array); + + $string = RegEx::replace( + '<([a-z][a-z0-9]*)(?: [^>]*)?>\s*(' . $comments . RegEx::quote($splitter) . $comments . ')\s*', + '\2', + $string + ); + + return explode($splitter, $string); + } + + /** + * Fix broken/invalid html syntax in a string using php DOMDocument functionality + * + * @param string $string + * + * @return mixed + */ + private static function fixUsingDOMDocument($string) + { + $doc = new DOMDocument; + + $doc->substituteEntities = false; + + // Add temporary surrounding div + $string = '
' . $string . '
'; + + @$doc->loadHTML($string); + $string = $doc->saveHTML(); + + // Remove html document structures + $string = RegEx::replace('^<[^>]*>(.*?).*?(?:(.*).*?)?(.*).*?$', '\1\2\3', $string); + + // Remove temporary surrounding div + $string = RegEx::replace('^\s*
(.*)
\s*$', '\1', $string); + + // Remove leading/trailing empty paragraph + $string = RegEx::replace('(^\s*
\s*
|
\s*
\s*$)', '', $string); + + // Remove leading/trailing empty paragraph + $string = RegEx::replace('(^\s*]*)?>\s*

|]*)?>\s*

\s*$)', '', $string); + + return $string; + } + + /** + * Fix broken/invalid html syntax in a string using custom code as an alternative to php DOMDocument functionality + * + * @param string $string + * + * @return string + */ + private static function fixUsingCustomFixer($string) + { + $block_regex = '<(' . implode('|', self::getBlockElementsNoDiv()) . ')[\s>]'; + + $string = RegEx::replace('(' . $block_regex . ')', '[:SPLIT-BLOCK:]\1', $string); + $parts = explode('[:SPLIT-BLOCK:]', $string); + + foreach ($parts as $i => &$part) + { + if ( ! RegEx::match('^' . $block_regex, $part, $type)) + { + continue; + } + + $type = strtolower($type[1]); + + // remove endings of other block elements + $part = RegEx::replace('', '', $part); + + if (strpos($part, '') !== false) + { + continue; + } + + // Add ending tag once + $part = RegEx::replaceOnce('(\s*)$', '\1', $part); + + // Remove empty block tags + $part = RegEx::replace('^<' . $type . '(?: [^>]*)?>\s*', '', $part); + } + + return implode('', $parts); + } + + /** + * Removes complete html tag pairs from the concatenated parts + * + * @param array $parts + * @param array $elements + * + * @return array + */ + public static function cleanSurroundingTags($parts, $elements = ['p', 'span']) + { + $breaks = '(?:(?:
|<\!--.*?-->|:\|:)\s*)*'; + $keys = array_keys($parts); + + $string = implode(':|:', $parts); + + // Remove empty tags + $regex = '<(' . implode('|', $elements) . ')(?: [^>]*)?>\s*(' . $breaks . ')<\/\1>\s*'; + + while (RegEx::match($regex, $string, $match)) + { + $string = str_replace($match[0], $match[2], $string); + } + + // Remove paragraphs around block elements + $block_elements = [ + 'p', 'div', + 'table', 'tr', 'td', 'thead', 'tfoot', + 'h[1-6]', + ]; + $block_elements = '(' . implode('|', $block_elements) . ')'; + + $regex = '(]*)?>)(\s*' . $breaks . ')(<' . $block_elements . '(?: [^>]*)?>)'; + + while (RegEx::match($regex, $string, $match)) + { + if ($match[4] == 'p') + { + $match[3] = $match[1] . $match[3]; + self::combinePTags($match[3]); + } + + $string = str_replace($match[0], $match[2] . $match[3], $string); + } + + $regex = '(\s*' . $breaks . ')

'; + + while (RegEx::match($regex, $string, $match)) + { + $string = str_replace($match[0], $match[1], $string); + } + + $parts = explode(':|:', $string); + + $new_tags = []; + + foreach ($parts as $key => $val) + { + $key = isset($keys[$key]) ? $keys[$key] : $key; + $new_tags[$key] = $val; + } + + return $new_tags; + } + + /** + * Remove

tags around block elements + * + * @param string $string + * + * @return mixed + */ + private static function removeParagraphsAroundBlockElements($string) + { + if (strpos($string, '

') == false) + { + return $string; + } + + $string = RegEx::replace( + ']*)?>\s*' + . '((?:<\!--.*?-->\s*)*]*)?>)', + '\1', + $string + ); + + $string = RegEx::replace( + '(]*)?>(?:\s*<\!--.*?-->)*)' + . '(?:\s*

)', + '\1', + $string + ); + + return $string; + } + + /** + * Remove

tags around comments + * + * @param string $string + * + * @return mixed + */ + private static function removeParagraphsAroundComments($string) + { + if (strpos($string, '

') == false) + { + return $string; + } + + $string = RegEx::replace( + '(?:]*)?>\s*)' + . '(<\!--.*?-->)' + . '(?:\s*

)', + '\1', + $string + ); + + return $string; + } + + /** + * Fix

tags around other

elements + * + * @param string $string + * + * @return mixed + */ + private static function fixParagraphsAroundParagraphElements($string) + { + if (strpos($string, '

') == false) + { + return $string; + } + + $parts = explode('

', $string); + $ending = '

' . array_pop($parts); + + foreach ($parts as &$part) + { + if (strpos($part, '

') === false && strpos($part, '

]*)?>.*?)(]*)?>)', + '\1

\2', + $part + ); + } + + return implode('

', $parts) . $ending; + } + + /* + * Remove empty tags + * + * @param string $string + * @param array $elements + * + * @return mixed + */ + public static function removeEmptyTagPairs($string, $elements = ['p', 'span']) + { + $breaks = '(?:(?:
|<\!--.*?-->)\s*)*'; + + $regex = '<(' . implode('|', $elements) . ')(?: [^>]*)?>\s*(' . $breaks . ')<\/\1>\s*'; + + while (RegEx::match($regex, $string, $match)) + { + $string = str_replace($match[0], $match[2], $string); + } + + return $string; + } + + /** + * Convert
tags inside inline elements to tags + * + * @param string $string + * + * @return mixed + */ + private static function convertDivsInsideInlineElementsToSpans($string) + { + if (strpos($string, '
') == false) + { + return $string; + } + + // Ignore block elements inside anchors + $regex = '<(' . implode('|', self::getInlineElementsNoAnchor()) . ')(?: [^>]*)?>.*?'; + RegEx::matchAll($regex, $string, $matches, '', PREG_PATTERN_ORDER); + + if (empty($matches)) + { + return $string; + } + + $matches = array_unique($matches[0]); + $searches = []; + $replacements = []; + + foreach ($matches as $match) + { + if (strpos($match, '
') === false) + { + continue; + } + + $searches[] = $match; + $replacements[] = str_replace( + ['
', '
'], + ['', ''], + $match + ); + } + + if (empty($searches)) + { + return $string; + } + + return str_replace($searches, $replacements, $string); + } + + /** + * Combine duplicate

tags + * input:

+ * output:

+ * + * @param $string + */ + public static function combinePTags(&$string) + { + if (empty($string)) + { + return; + } + + $p_start_tag = ']*)?>'; + $optional_tags = '\s*(?:<\!--.*?-->| |&\#160;)*\s*'; + RegEx::matchAll('(' . $p_start_tag . ')(' . $optional_tags . ')(' . $p_start_tag . ')', $string, $tags); + + if (empty($tags)) + { + return; + } + + foreach ($tags as $tag) + { + $string = str_replace($tag[0], $tag[2] . HtmlTag::combine($tag[1], $tag[3]), $string); + } + } + + /** + * Remove inline elements around block elements + * + * @param string $string + * + * @return mixed + */ + public static function removeInlineElementsAroundBlockElements($string) + { + $string = RegEx::replace( + '(?:<(?:' . implode('|', self::getInlineElementsNoAnchor()) . ')(?: [^>]*)?>\s*)' + . '(]*)?>)', + '\1', + $string + ); + + $string = RegEx::replace( + '(]*)?>)' + . '(?:\s*)', + '\1', + $string + ); + + return $string; + } + + /** + * Return an array of block element names, optionally without any of the names given $exclude + * + * @param array $exclude + * + * @return array + */ + public static function getBlockElements($exclude = []) + { + if ( ! is_array($exclude)) + { + $exclude = [$exclude]; + } + + $elements = [ + 'div', 'p', 'pre', + 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', + ]; + + $elements = array_diff($elements, $exclude); + + $elements = implode(',', $elements); + $elements = str_replace('h1,h2,h3,h4,h5,h6', 'h[1-6]', $elements); + $elements = explode(',', $elements); + + return $elements; + } + + /** + * Return an array of inline element names, optionally without any of the names given $exclude + * + * @param array $exclude + * + * @return array + */ + public static function getInlineElements($exclude = []) + { + if ( ! is_array($exclude)) + { + $exclude = [$exclude]; + } + + $elements = [ + 'span', 'code', 'a', + 'strong', 'b', 'em', 'i', 'u', 'big', 'small', 'font', + 'sup', 'sub', + ]; + + return array_diff($elements, $exclude); + } + + /** + * Return an array of block element names, without divs and any of the names given $exclude + * + * @param array $exclude + * + * @return array + */ + public static function getBlockElementsNoDiv($exclude = []) + { + return array_diff(self::getBlockElements($exclude), ['div']); + } + + /** + * Return an array of block element names, without anchors (a) and any of the names given $exclude + * + * @param array $exclude + * + * @return array + */ + public static function getInlineElementsNoAnchor($exclude = []) + { + return array_diff(self::getInlineElements($exclude), ['a']); + } + + /** + * Protect plugin style tags and php + * + * @param $string + * + * @return mixed + */ + private static function protectSpecialCode($string) + { + // Protect PHP code + Protect::protectByRegex($string, '(<|<)\?php\s.*?\?(>|>)'); + + // Protect {...} tags + Protect::protectByRegex($string, '\{[a-z0-9].*?\}'); + + // Protect [...] tags + Protect::protectByRegex($string, '\[[a-z0-9].*?\]'); + + // Protect scripts + Protect::protectByRegex($string, ']*>.*?'); + + // Protect css + Protect::protectByRegex($string, ']*>.*?'); + + Protect::convertProtectionToHtmlSafe($string); + + return $string; + } + + /** + * Unprotect protected tags + * + * @param $string + * + * @return mixed + */ + private static function unprotectSpecialCode($string) + { + Protect::unprotectHtmlSafe($string); + + return $string; + } + + /** + * Prevents broken html tags at the end of $pre (other half at beginning of $string) + * It will move the broken part to the beginning of $string to complete it + * + * @param $pre + * @param $string + */ + private static function fixBrokenTagsByPreString(&$pre, &$string) + { + if ( ! RegEx::match('<(\![^>]*|/?[a-z][^>]*(="[^"]*)?)$', $pre, $match)) + { + return; + } + + $pre = substr($pre, 0, strlen($pre) - strlen($match[0])); + $string = $match[0] . $string; + } + + /** + * Prevents broken html tags at the beginning of $pre (other half at end of $string) + * It will move the broken part to the end of $string to complete it + * + * @param $post + * @param $string + */ + private static function fixBrokenTagsByPostString(&$post, &$string) + { + if ( ! RegEx::match('<(\![^>]*|/?[a-z][^>]*(="[^"]*)?)$', $string, $match)) + { + return; + } + + if ( ! RegEx::match('^[^>]*>', $post, $match)) + { + return; + } + + $post = substr($post, strlen($match[0])); + + $string .= $match[0]; + } + + /** + * Removes html tags from string + * + * @param string $string + * + * @return string + */ + public static function removeHtmlTags($string) + { + // remove pagenavcounter + $string = RegEx::replace('

', ' ', $string); + // remove pagenavbar + $string = RegEx::replace('', ' ', $string); + // remove inline scripts + $string = RegEx::replace('', '', $string); + $string = RegEx::replace('', '', $string); + // remove inline styles + $string = RegEx::replace('', '', $string); + // remove inline html tags + $string = RegEx::replace( + ']*)?>', + '', + $string + ); + // replace other tags with a space + $string = RegEx::replace('', ' ', $string); + // remove double whitespace + $string = trim(RegEx::replace('(\s)[ ]+', '\1', $string)); + + return $string; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/src/HtmlTag.php b/deployed/regularlabs/libraries/regularlabs/src/HtmlTag.php new file mode 100644 index 00000000..c2759542 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/src/HtmlTag.php @@ -0,0 +1,168 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Library; + +defined('_JEXEC') or die; + +/** + * Class HtmlTag + * @package RegularLabs\Library + */ +class HtmlTag +{ + /** + * Combine 2 opening html tags into one + * + * @param string $tag1 + * @param string $tag2 + * + * @return string + */ + public static function combine($tag1, $tag2) + { + // Return if tags are the same + if ($tag1 == $tag2) + { + return $tag1; + } + + if ( ! RegEx::match('<([a-z][a-z0-9]*)', $tag1, $tag_type)) + { + return $tag2; + } + + $tag_type = $tag_type[1]; + + if ( ! $attribs = self::combineAttributes($tag1, $tag2)) + { + return '<' . $tag_type . '>'; + } + + return '<' . $tag_type . ' ' . $attribs . '>'; + } + + /** + * Extract attribute value from a html tag string by given attribute key + * + * @param string $key + * @param string $string + * + * @return string + */ + public static function getAttributeValue($key, $string) + { + if (empty($key) || empty($string)) + { + return ''; + } + + RegEx::match(RegEx::quote($key) . '="([^"]*)"', $string, $match); + + if (empty($match)) + { + return ''; + } + + return $match[1]; + } + + /** + * Extract all attributes from a html tag string + * + * @param string $string + * + * @return array + */ + public static function getAttributes($string) + { + if (empty($string)) + { + return []; + } + + RegEx::matchAll('([a-z0-9-_]+)="([^"]*)"', $string, $matches); + + if (empty($matches)) + { + return []; + } + + $attribs = []; + + foreach ($matches as $match) + { + $attribs[$match[1]] = $match[2]; + } + + return $attribs; + } + + /** + * Combine attribute values from 2 given html tag strings (or arrays of attributes) + * And return as a sting of attributes + * + * @param string /array $string1 + * @param string /array $string2 + * + * @return string + */ + public static function combineAttributes($string1, $string2, $flatten = true) + { + $attribsutes1 = is_array($string1) ? $string1 : self::getAttributes($string1); + $attribsutes2 = is_array($string2) ? $string2 : self::getAttributes($string2); + + $duplicate_attributes = array_intersect_key($attribsutes1, $attribsutes2); + + // Fill $attributes with the unique ids + $attributes = array_diff_key($attribsutes1, $attribsutes2) + array_diff_key($attribsutes2, $attribsutes1); + + // List of attrubute types that can only contain one value + $single_value_attributes = ['id', 'href']; + + // Add/combine the duplicate ids + foreach ($duplicate_attributes as $key => $val) + { + if (in_array($key, $single_value_attributes)) + { + $attributes[$key] = $attribsutes2[$key]; + continue; + } + // Combine strings, but remove duplicates + // "aaa bbb" + "aaa ccc" = "aaa bbb ccc" + + // use a ';' as a concatenated for javascript values (keys beginning with 'on') + // Otherwise use a space (like for classes) + $glue = substr($key, 0, 2) == 'on' ? ';' : ' '; + + $attributes[$key] = implode($glue, array_merge(explode($glue, $attribsutes1[$key]), explode($glue, $attribsutes2[$key]))); + } + + return $flatten ? self::flattenAttributes($attributes) : $attributes; + } + + /** + * Convert array of attributes to a html style string + * + * @param array $attributes + * + * @return string + */ + public static function flattenAttributes($attributes) + { + foreach ($attributes as $key => &$val) + { + $val = $key . '="' . $val . '"'; + } + + return implode(' ', $attributes); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/src/Http.php b/deployed/regularlabs/libraries/regularlabs/src/Http.php new file mode 100644 index 00000000..5f70a85f --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/src/Http.php @@ -0,0 +1,187 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Library; + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; +use Joomla\CMS\Http\HttpFactory as JHttpFactory; +use Joomla\Registry\Registry; +use RuntimeException; + +/** + * Class Http + * @package RegularLabs\Library + */ +class Http +{ + /** + * Get the contents of the given internal url + * + * @param string $url + * @param int $timeout + * + * @return string + */ + public static function get($url, $timeout = 20) + { + if (Uri::isExternal($url)) + { + return ''; + } + + return self::getFromUrl($url, $timeout); + } + + /** + * Get the contents of the given url + * + * @param string $url + * @param int $timeout + * + * @return string + */ + public static function getFromUrl($url, $timeout = 20) + { + $cache_id = 'getUrl_' . $url; + + if (Cache::has($cache_id)) + { + return Cache::get($cache_id); + } + + if (JFactory::getApplication()->input->getInt('cache', 0) + && $content = Cache::read($cache_id) + ) + { + return $content; + } + + $content = self::getContents($url, $timeout); + + if (empty($content)) + { + return ''; + } + + if ($ttl = JFactory::getApplication()->input->getInt('cache', 0)) + { + return Cache::write($cache_id, $content, $ttl > 1 ? $ttl : 0); + } + + return Cache::set($cache_id, $content); + } + + /** + * Get the contents of the given external url from the Regular Labs server + * + * @param string $url + * @param int $timeout + * + * @return string + */ + public static function getFromServer($url, $timeout = 20) + { + $cache_id = 'getByUrl_' . $url; + + if (Cache::has($cache_id)) + { + return Cache::get($cache_id); + } + + // only allow url calls from administrator + if ( ! Document::isClient('administrator')) + { + die; + } + + // only allow when logged in + $user = JFactory::getUser(); + if ( ! $user->id) + { + die; + } + + if (substr($url, 0, 4) != 'http') + { + $url = 'http://' . $url; + } + + // only allow url calls to regularlabs.com domain + if ( ! (RegEx::match('^https?://([^/]+\.)?regularlabs\.com/', $url))) + { + die; + } + + // only allow url calls to certain files + if ( + strpos($url, 'download.regularlabs.com/extensions.php') === false + && strpos($url, 'download.regularlabs.com/extensions.json') === false + && strpos($url, 'download.regularlabs.com/extensions.xml') === false + ) + { + die; + } + + $content = self::getContents($url, $timeout); + + if (empty($content)) + { + return ''; + } + + $format = (strpos($url, '.json') !== false || strpos($url, 'format=json') !== false) + ? 'application/json' + : 'text/xml'; + + header("Pragma: public"); + header("Expires: 0"); + header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); + header("Cache-Control: public"); + header("Content-type: " . $format); + + if ($ttl = JFactory::getApplication()->input->getInt('cache', 0)) + { + return Cache::write($cache_id, $content, $ttl > 1 ? $ttl : 0); + } + + return Cache::set($cache_id, $content); + } + + /** + * Load the contents of the given url + * + * @param string $url + * @param int $timeout + * + * @return string + */ + private static function getContents($url, $timeout = 20) + { + try + { + // Adding a valid user agent string, otherwise some feed-servers returning an error + $options = new Registry([ + 'userAgent' => 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0', + ]); + + $content = JHttpFactory::getHttp($options)->get($url, null, $timeout)->body; + } + catch (RuntimeException $e) + { + return ''; + } + + return $content; + } + +} diff --git a/deployed/regularlabs/libraries/regularlabs/src/Image.php b/deployed/regularlabs/libraries/regularlabs/src/Image.php new file mode 100644 index 00000000..9872f0f6 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/src/Image.php @@ -0,0 +1,357 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Library; + +defined('_JEXEC') or die; + +use JFolder; +use Joomla\CMS\Image\Image as JImage; +use Joomla\CMS\Uri\Uri as JUri; + +class Image +{ +// public static function getSet($source, $width, $height, $folder = 'resized', $resize = true, $quality = 'medium', $possible_suffix = '') +// { +// $paths = self::getPaths($source, $width, $height, $folder, $resize, $quality, $possible_suffix); +// +// return (object) [ +// 'original' => (object) [ +// 'url' => $paths->image, +// 'width' => self::getWidth($paths->original), +// 'height' => self::getHeight($paths->original), +// ], +// 'resized' => (object) [ +// 'url' => $paths->resized, +// 'width' => self::getWidth($paths->resized), +// 'height' => self::getHeight($paths->resized), +// ], +// ]; +// } + + public static function getUrls($source, $width, $height, $folder = 'resized', $resize = true, $quality = 'medium', $possible_suffix = '') + { + if ($image = self::isResized($source, $folder, $possible_suffix)) + { + $source = $image; + } + + $original = $source; + $resized = self::getResize($source, $width, $height, $folder, $resize, $quality); + + return (object) compact('original', 'resized'); + } + + public static function getResize($source, $width, $height, $folder = 'resized', $resize = true, $quality = 'medium') + { + $destination_folder = File::getDirName($source) . '/' . $folder; + + $override = File::getDirName($source) . '/' . $folder . '/' . File::getBaseName($source); + + if (file_exists(JPATH_SITE . '/' . $override)) + { + $source = $override; + } + + if ( ! self::setNewDimensions($source, $width, $height)) + { + return $source; + } + + if ( ! $width && ! $height) + { + return $source; + } + + $destination = self::getNewPath( + $source, + $width, + $height, + $destination_folder + ); + + if ( ! file_exists(JPATH_SITE . '/' . $destination) && $resize) + { + // Create new resized image + $destination = self::resize( + $source, + $width, + $height, + $destination_folder, + $quality + ); + } + + if ( ! file_exists(JPATH_SITE . '/' . $destination)) + { + return $source; + } + + return $destination; + } + + public static function isResized($file, $folder = 'resized', $possible_suffix = '') + { + if (File::isExternal($file)) + { + return false; + } + + if ( ! file_exists($file)) + { + return false; + } + + if ($main_image = self::isResizedWithFolder($file, $folder)) + { + return $main_image; + } + + if ($possible_suffix && $main_image = self::isResizedWithSuffix($file, $possible_suffix)) + { + return $main_image; + } + + return false; + } + + public static function isResizedWithSuffix($file, $suffix = '_t') + { + // Remove the suffix from the file + // image_t.jpg => image.jpg + $main_file = RegEx::replace( + RegEx::quote($suffix) . '(\.[^.]+)$', + '\1', + $file + ); + + // Nothing removed, so not a resized image + if ($main_file == $file) + { + return false; + } + + if ( ! file_exists(JPATH_SITE . '/' . utf8_decode($main_file))) + { + return false; + } + + return $main_file; + } + + private static function isResizedWithFolder($file, $resize_folder = 'resized') + { + $folder = File::getDirName($file); + $file = File::getBaseName($file); + $parent_folder_name = File::getBaseName($folder); + $parent_folder = File::getDirName($folder); + + // Image is not inside the resize folder + if ($parent_folder_name != $resize_folder) + { + return false; + } + + // Check if image with same name exists in parent folder + if (file_exists(JPATH_SITE . '/' . $parent_folder . '/' . utf8_decode($file))) + { + return $parent_folder . '/' . $file; + } + + // Remove any dimensions from the file + // image_300x200.jpg => image.jpg + $file = RegEx::replace( + '_[0-9]+x[0-9]*(\.[^.]+)$', + '\1', + $file + ); + + // Check again if image with same name (but without dimensions) exists in parent folder + if (file_exists(JPATH_SITE . '/' . $parent_folder . '/' . utf8_decode($file))) + { + return $parent_folder . '/' . $file; + } + + return false; + } + + public static function resize($source, &$width, &$height, $destination_folder = '', $quality = 'medium', $overwrite = false) + { + if (File::isExternal($source)) + { + return $source; + } + + $clean_source = ltrim(str_replace(JUri::root(), '', $source), '/'); + $source_path = JPATH_SITE . '/' . $clean_source; + + $destination_folder = ltrim($destination_folder ?: File::getDirName($clean_source)); + + if ( ! file_exists($source_path)) + { + return false; + } + + if ( ! self::setNewDimensions($source, $width, $height)) + { + return $source; + } + + if ( ! $width && ! $height) + { + return $source; + } + + $image = new JImage($source_path); + + $destination = self::getNewPath($source, $width, $height, $destination_folder); + $destination_path = JPATH_SITE . '/' . $destination; + + if (file_exists($destination_path) && ! $overwrite) + { + return $destination; + } + + JFolder::create(JPATH_SITE . '/' . $destination_folder); + + $info = JImage::getImageFileProperties($source_path); + + $options = ['quality' => self::getQuality($info->type, $quality)]; + + $image->cropResize($width, $height, false) + ->toFile($destination_path, $info->type, $options); + + $image->destroy(); + + return $destination; + } + + public static function setNewDimensions($source, &$width, &$height) + { + if ( ! $width && ! $height) + { + return false; + } + + if (File::isExternal($source)) + { + return false; + } + + $clean_source = ltrim(str_replace(JUri::root(), '', $source), '/'); + $source_path = JPATH_SITE . '/' . $clean_source; + + if ( ! file_exists($source_path)) + { + return false; + } + + $image = new JImage($source_path); + + $original_width = $image->getWidth(); + $original_height = $image->getHeight(); + + $width = $width ?: round($original_width / $original_height * $height); + $height = $height ?: round($original_height / $original_width * $width); + + $image->destroy(); + + if ($width == $original_width && $height == $original_height) + { + return false; + } + + return true; + } + + public static function getNewPath($source, $width, $height, $destination_folder = '') + { + $clean_source = self::cleanPath($source); + + $source_parts = pathinfo($clean_source); + + $destination_folder = ltrim($destination_folder ?: File::getDirName($clean_source)); + $destination_file = File::getFileName($clean_source) . '_' . $width . 'x' . $height . '.' . $source_parts['extension']; + + JFolder::create(JPATH_SITE . '/' . $destination_folder); + + return ltrim($destination_folder . '/' . $destination_file); + } + + public static function cleanPath($source) + { + return ltrim(str_replace(JUri::root(), '', $source), '/'); + } + + public static function getWidth($source) + { + $dimensions = self::getDimensions($source); + + return $dimensions->width; + } + + public static function getHeight($source) + { + $dimensions = self::getDimensions($source); + + return $dimensions->height; + } + + public static function getDimensions($source) + { + if (File::isExternal($source)) + { + return (object) [ + 'width' => 0, + 'height' => 0, + ]; + } + + $image = new JImage(JPATH_SITE . '/' . $source); + + return (object) [ + 'width' => $image->getWidth(), + 'height' => $image->getHeight(), + ]; + } + + public static function getQuality($type, $quality = 'medium') + { + switch ($type) + { + case IMAGETYPE_JPEG: + return min(max(self::getJpgQuality($quality), 0), 100); + + case IMAGETYPE_PNG: + return 9; + + default: + return ''; + } + } + + public static function getJpgQuality($quality = 'medium') + { + switch ($quality) + { + case 'low': + return 50; + + case 'high': + return 90; + + case 'medium': + default: + return 70; + } + } + +} diff --git a/deployed/regularlabs/libraries/regularlabs/src/Language.php b/deployed/regularlabs/libraries/regularlabs/src/Language.php new file mode 100644 index 00000000..809a1726 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/src/Language.php @@ -0,0 +1,44 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Library; + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; + +/** + * Class Language + * @package RegularLabs\Library + */ +class Language +{ + /** + * Load the language of the given extension + * + * @param string $extension + * @param string $basePath + * @param bool $reload + * + * @return bool + */ + public static function load($extension = 'plg_system_regularlabs', $basePath = '', $reload = false) + { + if ($basePath && JFactory::getLanguage()->load($extension, $basePath, null, $reload)) + { + return true; + } + + $basePath = Extension::getPath($extension, $basePath, 'language'); + + return JFactory::getLanguage()->load($extension, $basePath, null, $reload); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/src/License.php b/deployed/regularlabs/libraries/regularlabs/src/License.php new file mode 100644 index 00000000..7114c425 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/src/License.php @@ -0,0 +1,78 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Library; + +defined('_JEXEC') or die; + +use Joomla\CMS\Language\Text as JText; + +/** + * Class Language + * @package RegularLabs\Library + */ +class License +{ + /** + * Render the license message for Free versions + * + * @param string $name + * @param bool $check_pro + * + * @return string + */ + public static function getMessage($name, $check_pro = false) + { + if ( ! $name) + { + return ''; + } + + $alias = Extension::getAliasByName($name); + $name = Extension::getNameByAlias($name); + + if ($check_pro && self::isPro($alias)) + { + return ''; + } + + Document::loadMainDependencies(); + + return + '
' + . JText::sprintf('RL_IS_FREE_VERSION', $name) + . '
' + . JText::_('RL_FOR_MORE_GO_PRO') + . '
' + . '' + . ' ' + . StringHelper::html_entity_decoder(JText::_('RL_GO_PRO')) + . '' + . '
'; + } + + /** + * Check if the installed version of the extension is a Pro version + * + * @param string $element_name + * + * @return bool + */ + private static function isPro($element_name) + { + if ( ! $version = Extension::getXMLValue('version', $element_name)) + { + return false; + } + + return (stripos($version, 'PRO') !== false); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/src/Log.php b/deployed/regularlabs/libraries/regularlabs/src/Log.php new file mode 100644 index 00000000..d384d511 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/src/Log.php @@ -0,0 +1,107 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Library; + +defined('_JEXEC') or die; + +use JLoader; +use Joomla\CMS\Factory as JFactory; +use Joomla\CMS\MVC\Model\BaseDatabaseModel as JModel; + +/** + * Class Log + * @package RegularLabs\Library + */ +class Log +{ + public static function add($message, $languageKey, $context) + { + $user = JFactory::getUser(); + + $message['userid'] = $user->id; + $message['username'] = $user->username; + $message['accountlink'] = 'index.php?option=com_users&task=user.edit&id=' . $user->id; + + JLoader::register('ActionlogsHelper', JPATH_ADMINISTRATOR . '/components/com_actionlogs/helpers/actionlogs.php'); + JLoader::register('ActionlogsModelActionlog', JPATH_ADMINISTRATOR . '/components/com_actionlogs/models/actionlog.php'); + + $model = JModel::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog([$message], $languageKey, $context, $user->id); + } + + public static function save($message, $context, $isNew) + { + $languageKey = $isNew ? 'PLG_SYSTEM_ACTIONLOGS_CONTENT_ADDED' : 'PLG_SYSTEM_ACTIONLOGS_CONTENT_UPDATED'; + $message['action'] = $isNew ? 'add' : 'update'; + + self::add($message, $languageKey, $context); + } + + public static function delete($message, $context) + { + $languageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_DELETED'; + $message['action'] = 'deleted'; + + self::add($message, $languageKey, $context); + } + + public static function changeState($message, $context, $value) + { + switch ($value) + { + case 0: + $languageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_UNPUBLISHED'; + $message['action'] = 'unpublish'; + break; + case 1: + $languageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_PUBLISHED'; + $message['action'] = 'publish'; + break; + case 2: + $languageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_ARCHIVED'; + $message['action'] = 'archive'; + break; + case -2: + $languageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_TRASHED'; + $message['action'] = 'trash'; + break; + default: + return; + } + + self::add($message, $languageKey, $context); + } + + public static function install($message, $context, $type = 'component') + { + $languageKey = 'PLG_ACTIONLOG_JOOMLA_' . strtoupper($type) . '_INSTALLED'; + if ( ! JFactory::getApplication()->getLanguage()->hasKey($languageKey)) + { + $languageKey = 'PLG_ACTIONLOG_JOOMLA_EXTENSION_INSTALLED'; + } + + $message['action'] = 'install'; + $message['type'] = 'PLG_ACTIONLOG_JOOMLA_TYPE_' . strtoupper($type); + + self::add($message, $languageKey, $context); + } + + public static function uninstall($message, $context, $type = 'component') + { + $languageKey = 'PLG_ACTIONLOG_JOOMLA_EXTENSION_UNINSTALLED'; + + $message['action'] = 'uninstall'; + $message['type'] = 'PLG_ACTIONLOG_JOOMLA_TYPE_' . strtoupper($type); + + self::add($message, $languageKey, $context); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/src/MobileDetect.php b/deployed/regularlabs/libraries/regularlabs/src/MobileDetect.php new file mode 100644 index 00000000..7f8a0b94 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/src/MobileDetect.php @@ -0,0 +1,1553 @@ + + * @author Nick Ilyin + * Original author: Victor Stanciu + * + * @version 2.8.32 + */ + +namespace RegularLabs\Library; + +defined('_JEXEC') or die; + +use BadMethodCallException; + +class MobileDetect +{ + /** + * Mobile detection type. + * + * @deprecated since version 2.6.9 + */ + const DETECTION_TYPE_MOBILE = 'mobile'; + + /** + * Extended detection type. + * + * @deprecated since version 2.6.9 + */ + const DETECTION_TYPE_EXTENDED = 'extended'; + + /** + * A frequently used regular expression to extract version #s. + * + * @deprecated since version 2.6.9 + */ + const VER = '([\w._\+]+)'; + + /** + * Top-level device. + */ + const MOBILE_GRADE_A = 'A'; + + /** + * Mid-level device. + */ + const MOBILE_GRADE_B = 'B'; + + /** + * Low-level device. + */ + const MOBILE_GRADE_C = 'C'; + + /** + * Stores the version number of the current release. + */ + const VERSION = '2.8.30'; + + /** + * A type for the version() method indicating a string return value. + */ + const VERSION_TYPE_STRING = 'text'; + + /** + * A type for the version() method indicating a float return value. + */ + const VERSION_TYPE_FLOAT = 'float'; + + /** + * A cache for resolved matches + * @var array + */ + protected $cache = []; + + /** + * The User-Agent HTTP header is stored in here. + * @var string + */ + protected $userAgent = null; + + /** + * HTTP headers in the PHP-flavor. So HTTP_USER_AGENT and SERVER_SOFTWARE. + * @var array + */ + protected $httpHeaders = []; + + /** + * CloudFront headers. E.g. CloudFront-Is-Desktop-Viewer, CloudFront-Is-Mobile-Viewer & CloudFront-Is-Tablet-Viewer. + * @var array + */ + protected $cloudfrontHeaders = []; + + /** + * The matching Regex. + * This is good for debug. + * @var string + */ + protected $matchingRegex = null; + + /** + * The matches extracted from the regex expression. + * This is good for debug. + * @var string + */ + protected $matchesArray = null; + + /** + * The detection type, using self::DETECTION_TYPE_MOBILE or self::DETECTION_TYPE_EXTENDED. + * + * @deprecated since version 2.6.9 + * + * @var string + */ + protected $detectionType = self::DETECTION_TYPE_MOBILE; + + /** + * HTTP headers that trigger the 'isMobile' detection + * to be true. + * + * @var array + */ + protected static $mobileHeaders = [ + + 'HTTP_ACCEPT' => [ + 'matches' => [ + // Opera Mini; @reference: http://dev.opera.com/articles/view/opera-binary-markup-language/ + 'application/x-obml2d', + // BlackBerry devices. + 'application/vnd.rim.html', + 'text/vnd.wap.wml', + 'application/vnd.wap.xhtml+xml', + ], + ], + 'HTTP_X_WAP_PROFILE' => null, + 'HTTP_X_WAP_CLIENTID' => null, + 'HTTP_WAP_CONNECTION' => null, + 'HTTP_PROFILE' => null, + // Reported by Opera on Nokia devices (eg. C3). + 'HTTP_X_OPERAMINI_PHONE_UA' => null, + 'HTTP_X_NOKIA_GATEWAY_ID' => null, + 'HTTP_X_ORANGE_ID' => null, + 'HTTP_X_VODAFONE_3GPDPCONTEXT' => null, + 'HTTP_X_HUAWEI_USERID' => null, + // Reported by Windows Smartphones. + 'HTTP_UA_OS' => null, + // Reported by Verizon, Vodafone proxy system. + 'HTTP_X_MOBILE_GATEWAY' => null, + // Seen this on HTC Sensation. SensationXE_Beats_Z715e. + 'HTTP_X_ATT_DEVICEID' => null, + // Seen this on a HTC. + 'HTTP_UA_CPU' => ['matches' => ['ARM']], + ]; + + /** + * List of mobile devices (phones). + * + * @var array + */ + protected static $phoneDevices = [ + 'iPhone' => '\biPhone\b|\biPod\b', // |\biTunes + 'BlackBerry' => 'BlackBerry|\bBB10\b|rim[0-9]+', + 'HTC' => 'HTC|HTC.*(Sensation|Evo|Vision|Explorer|6800|8100|8900|A7272|S510e|C110e|Legend|Desire|T8282)|APX515CKT|Qtek9090|APA9292KT|HD_mini|Sensation.*Z710e|PG86100|Z715e|Desire.*(A8181|HD)|ADR6200|ADR6400L|ADR6425|001HT|Inspire 4G|Android.*\bEVO\b|T-Mobile G1|Z520m|Android [0-9.]+; Pixel', + 'Nexus' => 'Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus.*Mobile|Nexus 4|Nexus 5|Nexus 6', + // @todo: Is 'Dell Streak' a tablet or a phone? ;) + 'Dell' => 'Dell[;]? (Streak|Aero|Venue|Venue Pro|Flash|Smoke|Mini 3iX)|XCD28|XCD35|\b001DL\b|\b101DL\b|\bGS01\b', + 'Motorola' => 'Motorola|DROIDX|DROID BIONIC|\bDroid\b.*Build|Android.*Xoom|HRI39|MOT-|A1260|A1680|A555|A853|A855|A953|A955|A956|Motorola.*ELECTRIFY|Motorola.*i1|i867|i940|MB200|MB300|MB501|MB502|MB508|MB511|MB520|MB525|MB526|MB611|MB612|MB632|MB810|MB855|MB860|MB861|MB865|MB870|ME501|ME502|ME511|ME525|ME600|ME632|ME722|ME811|ME860|ME863|ME865|MT620|MT710|MT716|MT720|MT810|MT870|MT917|Motorola.*TITANIUM|WX435|WX445|XT300|XT301|XT311|XT316|XT317|XT319|XT320|XT390|XT502|XT530|XT531|XT532|XT535|XT603|XT610|XT611|XT615|XT681|XT701|XT702|XT711|XT720|XT800|XT806|XT860|XT862|XT875|XT882|XT883|XT894|XT901|XT907|XT909|XT910|XT912|XT928|XT926|XT915|XT919|XT925|XT1021|\bMoto E\b|XT1068|XT1092|XT1052', + 'Samsung' => '\bSamsung\b|SM-G950F|SM-G955F|SM-G9250|GT-19300|SGH-I337|BGT-S5230|GT-B2100|GT-B2700|GT-B2710|GT-B3210|GT-B3310|GT-B3410|GT-B3730|GT-B3740|GT-B5510|GT-B5512|GT-B5722|GT-B6520|GT-B7300|GT-B7320|GT-B7330|GT-B7350|GT-B7510|GT-B7722|GT-B7800|GT-C3010|GT-C3011|GT-C3060|GT-C3200|GT-C3212|GT-C3212I|GT-C3262|GT-C3222|GT-C3300|GT-C3300K|GT-C3303|GT-C3303K|GT-C3310|GT-C3322|GT-C3330|GT-C3350|GT-C3500|GT-C3510|GT-C3530|GT-C3630|GT-C3780|GT-C5010|GT-C5212|GT-C6620|GT-C6625|GT-C6712|GT-E1050|GT-E1070|GT-E1075|GT-E1080|GT-E1081|GT-E1085|GT-E1087|GT-E1100|GT-E1107|GT-E1110|GT-E1120|GT-E1125|GT-E1130|GT-E1160|GT-E1170|GT-E1175|GT-E1180|GT-E1182|GT-E1200|GT-E1210|GT-E1225|GT-E1230|GT-E1390|GT-E2100|GT-E2120|GT-E2121|GT-E2152|GT-E2220|GT-E2222|GT-E2230|GT-E2232|GT-E2250|GT-E2370|GT-E2550|GT-E2652|GT-E3210|GT-E3213|GT-I5500|GT-I5503|GT-I5700|GT-I5800|GT-I5801|GT-I6410|GT-I6420|GT-I7110|GT-I7410|GT-I7500|GT-I8000|GT-I8150|GT-I8160|GT-I8190|GT-I8320|GT-I8330|GT-I8350|GT-I8530|GT-I8700|GT-I8703|GT-I8910|GT-I9000|GT-I9001|GT-I9003|GT-I9010|GT-I9020|GT-I9023|GT-I9070|GT-I9082|GT-I9100|GT-I9103|GT-I9220|GT-I9250|GT-I9300|GT-I9305|GT-I9500|GT-I9505|GT-M3510|GT-M5650|GT-M7500|GT-M7600|GT-M7603|GT-M8800|GT-M8910|GT-N7000|GT-S3110|GT-S3310|GT-S3350|GT-S3353|GT-S3370|GT-S3650|GT-S3653|GT-S3770|GT-S3850|GT-S5210|GT-S5220|GT-S5229|GT-S5230|GT-S5233|GT-S5250|GT-S5253|GT-S5260|GT-S5263|GT-S5270|GT-S5300|GT-S5330|GT-S5350|GT-S5360|GT-S5363|GT-S5369|GT-S5380|GT-S5380D|GT-S5560|GT-S5570|GT-S5600|GT-S5603|GT-S5610|GT-S5620|GT-S5660|GT-S5670|GT-S5690|GT-S5750|GT-S5780|GT-S5830|GT-S5839|GT-S6102|GT-S6500|GT-S7070|GT-S7200|GT-S7220|GT-S7230|GT-S7233|GT-S7250|GT-S7500|GT-S7530|GT-S7550|GT-S7562|GT-S7710|GT-S8000|GT-S8003|GT-S8500|GT-S8530|GT-S8600|SCH-A310|SCH-A530|SCH-A570|SCH-A610|SCH-A630|SCH-A650|SCH-A790|SCH-A795|SCH-A850|SCH-A870|SCH-A890|SCH-A930|SCH-A950|SCH-A970|SCH-A990|SCH-I100|SCH-I110|SCH-I400|SCH-I405|SCH-I500|SCH-I510|SCH-I515|SCH-I600|SCH-I730|SCH-I760|SCH-I770|SCH-I830|SCH-I910|SCH-I920|SCH-I959|SCH-LC11|SCH-N150|SCH-N300|SCH-R100|SCH-R300|SCH-R351|SCH-R400|SCH-R410|SCH-T300|SCH-U310|SCH-U320|SCH-U350|SCH-U360|SCH-U365|SCH-U370|SCH-U380|SCH-U410|SCH-U430|SCH-U450|SCH-U460|SCH-U470|SCH-U490|SCH-U540|SCH-U550|SCH-U620|SCH-U640|SCH-U650|SCH-U660|SCH-U700|SCH-U740|SCH-U750|SCH-U810|SCH-U820|SCH-U900|SCH-U940|SCH-U960|SCS-26UC|SGH-A107|SGH-A117|SGH-A127|SGH-A137|SGH-A157|SGH-A167|SGH-A177|SGH-A187|SGH-A197|SGH-A227|SGH-A237|SGH-A257|SGH-A437|SGH-A517|SGH-A597|SGH-A637|SGH-A657|SGH-A667|SGH-A687|SGH-A697|SGH-A707|SGH-A717|SGH-A727|SGH-A737|SGH-A747|SGH-A767|SGH-A777|SGH-A797|SGH-A817|SGH-A827|SGH-A837|SGH-A847|SGH-A867|SGH-A877|SGH-A887|SGH-A897|SGH-A927|SGH-B100|SGH-B130|SGH-B200|SGH-B220|SGH-C100|SGH-C110|SGH-C120|SGH-C130|SGH-C140|SGH-C160|SGH-C170|SGH-C180|SGH-C200|SGH-C207|SGH-C210|SGH-C225|SGH-C230|SGH-C417|SGH-C450|SGH-D307|SGH-D347|SGH-D357|SGH-D407|SGH-D415|SGH-D780|SGH-D807|SGH-D980|SGH-E105|SGH-E200|SGH-E315|SGH-E316|SGH-E317|SGH-E335|SGH-E590|SGH-E635|SGH-E715|SGH-E890|SGH-F300|SGH-F480|SGH-I200|SGH-I300|SGH-I320|SGH-I550|SGH-I577|SGH-I600|SGH-I607|SGH-I617|SGH-I627|SGH-I637|SGH-I677|SGH-I700|SGH-I717|SGH-I727|SGH-i747M|SGH-I777|SGH-I780|SGH-I827|SGH-I847|SGH-I857|SGH-I896|SGH-I897|SGH-I900|SGH-I907|SGH-I917|SGH-I927|SGH-I937|SGH-I997|SGH-J150|SGH-J200|SGH-L170|SGH-L700|SGH-M110|SGH-M150|SGH-M200|SGH-N105|SGH-N500|SGH-N600|SGH-N620|SGH-N625|SGH-N700|SGH-N710|SGH-P107|SGH-P207|SGH-P300|SGH-P310|SGH-P520|SGH-P735|SGH-P777|SGH-Q105|SGH-R210|SGH-R220|SGH-R225|SGH-S105|SGH-S307|SGH-T109|SGH-T119|SGH-T139|SGH-T209|SGH-T219|SGH-T229|SGH-T239|SGH-T249|SGH-T259|SGH-T309|SGH-T319|SGH-T329|SGH-T339|SGH-T349|SGH-T359|SGH-T369|SGH-T379|SGH-T409|SGH-T429|SGH-T439|SGH-T459|SGH-T469|SGH-T479|SGH-T499|SGH-T509|SGH-T519|SGH-T539|SGH-T559|SGH-T589|SGH-T609|SGH-T619|SGH-T629|SGH-T639|SGH-T659|SGH-T669|SGH-T679|SGH-T709|SGH-T719|SGH-T729|SGH-T739|SGH-T746|SGH-T749|SGH-T759|SGH-T769|SGH-T809|SGH-T819|SGH-T839|SGH-T919|SGH-T929|SGH-T939|SGH-T959|SGH-T989|SGH-U100|SGH-U200|SGH-U800|SGH-V205|SGH-V206|SGH-X100|SGH-X105|SGH-X120|SGH-X140|SGH-X426|SGH-X427|SGH-X475|SGH-X495|SGH-X497|SGH-X507|SGH-X600|SGH-X610|SGH-X620|SGH-X630|SGH-X700|SGH-X820|SGH-X890|SGH-Z130|SGH-Z150|SGH-Z170|SGH-ZX10|SGH-ZX20|SHW-M110|SPH-A120|SPH-A400|SPH-A420|SPH-A460|SPH-A500|SPH-A560|SPH-A600|SPH-A620|SPH-A660|SPH-A700|SPH-A740|SPH-A760|SPH-A790|SPH-A800|SPH-A820|SPH-A840|SPH-A880|SPH-A900|SPH-A940|SPH-A960|SPH-D600|SPH-D700|SPH-D710|SPH-D720|SPH-I300|SPH-I325|SPH-I330|SPH-I350|SPH-I500|SPH-I600|SPH-I700|SPH-L700|SPH-M100|SPH-M220|SPH-M240|SPH-M300|SPH-M305|SPH-M320|SPH-M330|SPH-M350|SPH-M360|SPH-M370|SPH-M380|SPH-M510|SPH-M540|SPH-M550|SPH-M560|SPH-M570|SPH-M580|SPH-M610|SPH-M620|SPH-M630|SPH-M800|SPH-M810|SPH-M850|SPH-M900|SPH-M910|SPH-M920|SPH-M930|SPH-N100|SPH-N200|SPH-N240|SPH-N300|SPH-N400|SPH-Z400|SWC-E100|SCH-i909|GT-N7100|GT-N7105|SCH-I535|SM-N900A|SGH-I317|SGH-T999L|GT-S5360B|GT-I8262|GT-S6802|GT-S6312|GT-S6310|GT-S5312|GT-S5310|GT-I9105|GT-I8510|GT-S6790N|SM-G7105|SM-N9005|GT-S5301|GT-I9295|GT-I9195|SM-C101|GT-S7392|GT-S7560|GT-B7610|GT-I5510|GT-S7582|GT-S7530E|GT-I8750|SM-G9006V|SM-G9008V|SM-G9009D|SM-G900A|SM-G900D|SM-G900F|SM-G900H|SM-G900I|SM-G900J|SM-G900K|SM-G900L|SM-G900M|SM-G900P|SM-G900R4|SM-G900S|SM-G900T|SM-G900V|SM-G900W8|SHV-E160K|SCH-P709|SCH-P729|SM-T2558|GT-I9205|SM-G9350|SM-J120F|SM-G920F|SM-G920V|SM-G930F|SM-N910C|SM-A310F|GT-I9190|SM-J500FN|SM-G903F|SM-J330F', + 'LG' => '\bLG\b;|LG[- ]?(C800|C900|E400|E610|E900|E-900|F160|F180K|F180L|F180S|730|855|L160|LS740|LS840|LS970|LU6200|MS690|MS695|MS770|MS840|MS870|MS910|P500|P700|P705|VM696|AS680|AS695|AX840|C729|E970|GS505|272|C395|E739BK|E960|L55C|L75C|LS696|LS860|P769BK|P350|P500|P509|P870|UN272|US730|VS840|VS950|LN272|LN510|LS670|LS855|LW690|MN270|MN510|P509|P769|P930|UN200|UN270|UN510|UN610|US670|US740|US760|UX265|UX840|VN271|VN530|VS660|VS700|VS740|VS750|VS910|VS920|VS930|VX9200|VX11000|AX840A|LW770|P506|P925|P999|E612|D955|D802|MS323|M257)', + 'Sony' => 'SonyST|SonyLT|SonyEricsson|SonyEricssonLT15iv|LT18i|E10i|LT28h|LT26w|SonyEricssonMT27i|C5303|C6902|C6903|C6906|C6943|D2533', + 'Asus' => 'Asus.*Galaxy|PadFone.*Mobile', + 'NokiaLumia' => 'Lumia [0-9]{3,4}', + // http://www.micromaxinfo.com/mobiles/smartphones + // Added because the codes might conflict with Acer Tablets. + 'Micromax' => 'Micromax.*\b(A210|A92|A88|A72|A111|A110Q|A115|A116|A110|A90S|A26|A51|A35|A54|A25|A27|A89|A68|A65|A57|A90)\b', + // @todo Complete the regex. + 'Palm' => 'PalmSource|Palm', // avantgo|blazer|elaine|hiptop|plucker|xiino ; + 'Vertu' => 'Vertu|Vertu.*Ltd|Vertu.*Ascent|Vertu.*Ayxta|Vertu.*Constellation(F|Quest)?|Vertu.*Monika|Vertu.*Signature', // Just for fun ;) + // http://www.pantech.co.kr/en/prod/prodList.do?gbrand=VEGA (PANTECH) + // Most of the VEGA devices are legacy. PANTECH seem to be newer devices based on Android. + 'Pantech' => 'PANTECH|IM-A850S|IM-A840S|IM-A830L|IM-A830K|IM-A830S|IM-A820L|IM-A810K|IM-A810S|IM-A800S|IM-T100K|IM-A725L|IM-A780L|IM-A775C|IM-A770K|IM-A760S|IM-A750K|IM-A740S|IM-A730S|IM-A720L|IM-A710K|IM-A690L|IM-A690S|IM-A650S|IM-A630K|IM-A600S|VEGA PTL21|PT003|P8010|ADR910L|P6030|P6020|P9070|P4100|P9060|P5000|CDM8992|TXT8045|ADR8995|IS11PT|P2030|P6010|P8000|PT002|IS06|CDM8999|P9050|PT001|TXT8040|P2020|P9020|P2000|P7040|P7000|C790', + // http://www.fly-phone.com/devices/smartphones/ ; Included only smartphones. + 'Fly' => 'IQ230|IQ444|IQ450|IQ440|IQ442|IQ441|IQ245|IQ256|IQ236|IQ255|IQ235|IQ245|IQ275|IQ240|IQ285|IQ280|IQ270|IQ260|IQ250', + // http://fr.wikomobile.com + 'Wiko' => 'KITE 4G|HIGHWAY|GETAWAY|STAIRWAY|DARKSIDE|DARKFULL|DARKNIGHT|DARKMOON|SLIDE|WAX 4G|RAINBOW|BLOOM|SUNSET|GOA(?!nna)|LENNY|BARRY|IGGY|OZZY|CINK FIVE|CINK PEAX|CINK PEAX 2|CINK SLIM|CINK SLIM 2|CINK +|CINK KING|CINK PEAX|CINK SLIM|SUBLIM', + 'iMobile' => 'i-mobile (IQ|i-STYLE|idea|ZAA|Hitz)', + // Added simvalley mobile just for fun. They have some interesting devices. + // http://www.simvalley.fr/telephonie---gps-_22_telephonie-mobile_telephones_.html + 'SimValley' => '\b(SP-80|XT-930|SX-340|XT-930|SX-310|SP-360|SP60|SPT-800|SP-120|SPT-800|SP-140|SPX-5|SPX-8|SP-100|SPX-8|SPX-12)\b', + // Wolfgang - a brand that is sold by Aldi supermarkets. + // http://www.wolfgangmobile.com/ + 'Wolfgang' => 'AT-B24D|AT-AS50HD|AT-AS40W|AT-AS55HD|AT-AS45q2|AT-B26D|AT-AS50Q', + 'Alcatel' => 'Alcatel', + 'Nintendo' => 'Nintendo (3DS|Switch)', + // http://en.wikipedia.org/wiki/Amoi + 'Amoi' => 'Amoi', + // http://en.wikipedia.org/wiki/INQ + 'INQ' => 'INQ', + // @Tapatalk is a mobile app; http://support.tapatalk.com/threads/smf-2-0-2-os-and-browser-detection-plugin-and-tapatalk.15565/#post-79039 + 'GenericPhone' => 'Tapatalk|PDA;|SAGEM|\bmmp\b|pocket|\bpsp\b|symbian|Smartphone|smartfon|treo|up.browser|up.link|vodafone|\bwap\b|nokia|Series40|Series60|S60|SonyEricsson|N900|MAUI.*WAP.*Browser', + ]; + + /** + * List of tablet devices. + * + * @var array + */ + protected static $tabletDevices = [ + // @todo: check for mobile friendly emails topic. + 'iPad' => 'iPad|iPad.*Mobile', + // Removed |^.*Android.*Nexus(?!(?:Mobile).)*$ + // @see #442 + // @todo Merge NexusTablet into GoogleTablet. + 'NexusTablet' => 'Android.*Nexus[\s]+(7|9|10)', + // https://en.wikipedia.org/wiki/Pixel_C + 'GoogleTablet' => 'Android.*Pixel C', + 'SamsungTablet' => 'SAMSUNG.*Tablet|Galaxy.*Tab|SC-01C|GT-P1000|GT-P1003|GT-P1010|GT-P3105|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P3100|GT-P3108|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7320|GT-P7511|GT-N8000|GT-P8510|SGH-I497|SPH-P500|SGH-T779|SCH-I705|SCH-I915|GT-N8013|GT-P3113|GT-P5113|GT-P8110|GT-N8010|GT-N8005|GT-N8020|GT-P1013|GT-P6201|GT-P7501|GT-N5100|GT-N5105|GT-N5110|SHV-E140K|SHV-E140L|SHV-E140S|SHV-E150S|SHV-E230K|SHV-E230L|SHV-E230S|SHW-M180K|SHW-M180L|SHW-M180S|SHW-M180W|SHW-M300W|SHW-M305W|SHW-M380K|SHW-M380S|SHW-M380W|SHW-M430W|SHW-M480K|SHW-M480S|SHW-M480W|SHW-M485W|SHW-M486W|SHW-M500W|GT-I9228|SCH-P739|SCH-I925|GT-I9200|GT-P5200|GT-P5210|GT-P5210X|SM-T311|SM-T310|SM-T310X|SM-T210|SM-T210R|SM-T211|SM-P600|SM-P601|SM-P605|SM-P900|SM-P901|SM-T217|SM-T217A|SM-T217S|SM-P6000|SM-T3100|SGH-I467|XE500|SM-T110|GT-P5220|GT-I9200X|GT-N5110X|GT-N5120|SM-P905|SM-T111|SM-T2105|SM-T315|SM-T320|SM-T320X|SM-T321|SM-T520|SM-T525|SM-T530NU|SM-T230NU|SM-T330NU|SM-T900|XE500T1C|SM-P605V|SM-P905V|SM-T337V|SM-T537V|SM-T707V|SM-T807V|SM-P600X|SM-P900X|SM-T210X|SM-T230|SM-T230X|SM-T325|GT-P7503|SM-T531|SM-T330|SM-T530|SM-T705|SM-T705C|SM-T535|SM-T331|SM-T800|SM-T700|SM-T537|SM-T807|SM-P907A|SM-T337A|SM-T537A|SM-T707A|SM-T807A|SM-T237|SM-T807P|SM-P607T|SM-T217T|SM-T337T|SM-T807T|SM-T116NQ|SM-T116BU|SM-P550|SM-T350|SM-T550|SM-T9000|SM-P9000|SM-T705Y|SM-T805|GT-P3113|SM-T710|SM-T810|SM-T815|SM-T360|SM-T533|SM-T113|SM-T335|SM-T715|SM-T560|SM-T670|SM-T677|SM-T377|SM-T567|SM-T357T|SM-T555|SM-T561|SM-T713|SM-T719|SM-T813|SM-T819|SM-T580|SM-T355Y?|SM-T280|SM-T817A|SM-T820|SM-W700|SM-P580|SM-T587|SM-P350|SM-P555M|SM-P355M|SM-T113NU|SM-T815Y|SM-T585|SM-T285|SM-T825|SM-W708', + // SCH-P709|SCH-P729|SM-T2558|GT-I9205 - Samsung Mega - treat them like a regular phone. + // http://docs.aws.amazon.com/silk/latest/developerguide/user-agent.html + 'Kindle' => 'Kindle|Silk.*Accelerated|Android.*\b(KFOT|KFTT|KFJWI|KFJWA|KFOTE|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|WFJWAE|KFSAWA|KFSAWI|KFASWI|KFARWI|KFFOWI|KFGIWI|KFMEWI)\b|Android.*Silk/[0-9.]+ like Chrome/[0-9.]+ (?!Mobile)', + // Only the Surface tablets with Windows RT are considered mobile. + // http://msdn.microsoft.com/en-us/library/ie/hh920767(v=vs.85).aspx + 'SurfaceTablet' => 'Windows NT [0-9.]+; ARM;.*(Tablet|ARMBJS)', + // http://shopping1.hp.com/is-bin/INTERSHOP.enfinity/WFS/WW-USSMBPublicStore-Site/en_US/-/USD/ViewStandardCatalog-Browse?CatalogCategoryID=JfIQ7EN5lqMAAAEyDcJUDwMT + 'HPTablet' => 'HP Slate (7|8|10)|HP ElitePad 900|hp-tablet|EliteBook.*Touch|HP 8|Slate 21|HP SlateBook 10', + // Watch out for PadFone, see #132. + // http://www.asus.com/de/Tablets_Mobile/Memo_Pad_Products/ + 'AsusTablet' => '^.*PadFone((?!Mobile).)*$|Transformer|TF101|TF101G|TF300T|TF300TG|TF300TL|TF700T|TF700KL|TF701T|TF810C|ME171|ME301T|ME302C|ME371MG|ME370T|ME372MG|ME172V|ME173X|ME400C|Slider SL101|\bK00F\b|\bK00C\b|\bK00E\b|\bK00L\b|TX201LA|ME176C|ME102A|\bM80TA\b|ME372CL|ME560CG|ME372CG|ME302KL| K010 | K011 | K017 | K01E |ME572C|ME103K|ME170C|ME171C|\bME70C\b|ME581C|ME581CL|ME8510C|ME181C|P01Y|PO1MA|P01Z|\bP027\b|\bP024\b|\bP00C\b', + 'BlackBerryTablet' => 'PlayBook|RIM Tablet', + 'HTCtablet' => 'HTC_Flyer_P512|HTC Flyer|HTC Jetstream|HTC-P715a|HTC EVO View 4G|PG41200|PG09410', + 'MotorolaTablet' => 'xoom|sholest|MZ615|MZ605|MZ505|MZ601|MZ602|MZ603|MZ604|MZ606|MZ607|MZ608|MZ609|MZ615|MZ616|MZ617', + 'NookTablet' => 'Android.*Nook|NookColor|nook browser|BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2', + // http://www.acer.ro/ac/ro/RO/content/drivers + // http://www.packardbell.co.uk/pb/en/GB/content/download (Packard Bell is part of Acer) + // http://us.acer.com/ac/en/US/content/group/tablets + // http://www.acer.de/ac/de/DE/content/models/tablets/ + // Can conflict with Micromax and Motorola phones codes. + 'AcerTablet' => 'Android.*; \b(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700|A701|W500|W500P|W501|W501P|W510|W511|W700|G100|G100W|B1-A71|B1-710|B1-711|A1-810|A1-811|A1-830)\b|W3-810|\bA3-A10\b|\bA3-A11\b|\bA3-A20\b|\bA3-A30', + // http://eu.computers.toshiba-europe.com/innovation/family/Tablets/1098744/banner_id/tablet_footerlink/ + // http://us.toshiba.com/tablets/tablet-finder + // http://www.toshiba.co.jp/regza/tablet/ + 'ToshibaTablet' => 'Android.*(AT100|AT105|AT200|AT205|AT270|AT275|AT300|AT305|AT1S5|AT500|AT570|AT700|AT830)|TOSHIBA.*FOLIO', + // http://www.nttdocomo.co.jp/english/service/developer/smart_phone/technical_info/spec/index.html + // http://www.lg.com/us/tablets + 'LGTablet' => '\bL-06C|LG-V909|LG-V900|LG-V700|LG-V510|LG-V500|LG-V410|LG-V400|LG-VK810\b', + 'FujitsuTablet' => 'Android.*\b(F-01D|F-02F|F-05E|F-10D|M532|Q572)\b', + // Prestigio Tablets http://www.prestigio.com/support + 'PrestigioTablet' => 'PMP3170B|PMP3270B|PMP3470B|PMP7170B|PMP3370B|PMP3570C|PMP5870C|PMP3670B|PMP5570C|PMP5770D|PMP3970B|PMP3870C|PMP5580C|PMP5880D|PMP5780D|PMP5588C|PMP7280C|PMP7280C3G|PMP7280|PMP7880D|PMP5597D|PMP5597|PMP7100D|PER3464|PER3274|PER3574|PER3884|PER5274|PER5474|PMP5097CPRO|PMP5097|PMP7380D|PMP5297C|PMP5297C_QUAD|PMP812E|PMP812E3G|PMP812F|PMP810E|PMP880TD|PMT3017|PMT3037|PMT3047|PMT3057|PMT7008|PMT5887|PMT5001|PMT5002', + // http://support.lenovo.com/en_GB/downloads/default.page?# + 'LenovoTablet' => 'Lenovo TAB|Idea(Tab|Pad)( A1|A10| K1|)|ThinkPad([ ]+)?Tablet|YT3-850M|YT3-X90L|YT3-X90F|YT3-X90X|Lenovo.*(S2109|S2110|S5000|S6000|K3011|A3000|A3500|A1000|A2107|A2109|A1107|A5500|A7600|B6000|B8000|B8080)(-|)(FL|F|HV|H|)|TB-X103F|TB-X304F|TB-X304L|TB-8703F|Tab2A7-10F', + // http://www.dell.com/support/home/us/en/04/Products/tab_mob/tablets + 'DellTablet' => 'Venue 11|Venue 8|Venue 7|Dell Streak 10|Dell Streak 7', + // http://www.yarvik.com/en/matrix/tablets/ + 'YarvikTablet' => 'Android.*\b(TAB210|TAB211|TAB224|TAB250|TAB260|TAB264|TAB310|TAB360|TAB364|TAB410|TAB411|TAB420|TAB424|TAB450|TAB460|TAB461|TAB464|TAB465|TAB467|TAB468|TAB07-100|TAB07-101|TAB07-150|TAB07-151|TAB07-152|TAB07-200|TAB07-201-3G|TAB07-210|TAB07-211|TAB07-212|TAB07-214|TAB07-220|TAB07-400|TAB07-485|TAB08-150|TAB08-200|TAB08-201-3G|TAB08-201-30|TAB09-100|TAB09-211|TAB09-410|TAB10-150|TAB10-201|TAB10-211|TAB10-400|TAB10-410|TAB13-201|TAB274EUK|TAB275EUK|TAB374EUK|TAB462EUK|TAB474EUK|TAB9-200)\b', + 'MedionTablet' => 'Android.*\bOYO\b|LIFE.*(P9212|P9514|P9516|S9512)|LIFETAB', + 'ArnovaTablet' => '97G4|AN10G2|AN7bG3|AN7fG3|AN8G3|AN8cG3|AN7G3|AN9G3|AN7dG3|AN7dG3ST|AN7dG3ChildPad|AN10bG3|AN10bG3DT|AN9G2', + // http://www.intenso.de/kategorie_en.php?kategorie=33 + // @todo: http://www.nbhkdz.com/read/b8e64202f92a2df129126bff.html - investigate + 'IntensoTablet' => 'INM8002KP|INM1010FP|INM805ND|Intenso Tab|TAB1004', + // IRU.ru Tablets http://www.iru.ru/catalog/soho/planetable/ + 'IRUTablet' => 'M702pro', + 'MegafonTablet' => 'MegaFon V9|\bZTE V9\b|Android.*\bMT7A\b', + // http://www.e-boda.ro/tablete-pc.html + 'EbodaTablet' => 'E-Boda (Supreme|Impresspeed|Izzycomm|Essential)', + // http://www.allview.ro/produse/droseries/lista-tablete-pc/ + 'AllViewTablet' => 'Allview.*(Viva|Alldro|City|Speed|All TV|Frenzy|Quasar|Shine|TX1|AX1|AX2)', + // http://wiki.archosfans.com/index.php?title=Main_Page + // @note Rewrite the regex format after we add more UAs. + 'ArchosTablet' => '\b(101G9|80G9|A101IT)\b|Qilive 97R|Archos5|\bARCHOS (70|79|80|90|97|101|FAMILYPAD|)(b|c|)(G10| Cobalt| TITANIUM(HD|)| Xenon| Neon|XSK| 2| XS 2| PLATINUM| CARBON|GAMEPAD)\b', + // http://www.ainol.com/plugin.php?identifier=ainol&module=product + 'AinolTablet' => 'NOVO7|NOVO8|NOVO10|Novo7Aurora|Novo7Basic|NOVO7PALADIN|novo9-Spark', + 'NokiaLumiaTablet' => 'Lumia 2520', + // @todo: inspect http://esupport.sony.com/US/p/select-system.pl?DIRECTOR=DRIVER + // Readers http://www.atsuhiro-me.net/ebook/sony-reader/sony-reader-web-browser + // http://www.sony.jp/support/tablet/ + 'SonyTablet' => 'Sony.*Tablet|Xperia Tablet|Sony Tablet S|SO-03E|SGPT12|SGPT13|SGPT114|SGPT121|SGPT122|SGPT123|SGPT111|SGPT112|SGPT113|SGPT131|SGPT132|SGPT133|SGPT211|SGPT212|SGPT213|SGP311|SGP312|SGP321|EBRD1101|EBRD1102|EBRD1201|SGP351|SGP341|SGP511|SGP512|SGP521|SGP541|SGP551|SGP621|SGP612|SOT31', + // http://www.support.philips.com/support/catalog/worldproducts.jsp?userLanguage=en&userCountry=cn&categoryid=3G_LTE_TABLET_SU_CN_CARE&title=3G%20tablets%20/%20LTE%20range&_dyncharset=UTF-8 + 'PhilipsTablet' => '\b(PI2010|PI3000|PI3100|PI3105|PI3110|PI3205|PI3210|PI3900|PI4010|PI7000|PI7100)\b', + // db + http://www.cube-tablet.com/buy-products.html + 'CubeTablet' => 'Android.*(K8GT|U9GT|U10GT|U16GT|U17GT|U18GT|U19GT|U20GT|U23GT|U30GT)|CUBE U8GT', + // http://www.cobyusa.com/?p=pcat&pcat_id=3001 + 'CobyTablet' => 'MID1042|MID1045|MID1125|MID1126|MID7012|MID7014|MID7015|MID7034|MID7035|MID7036|MID7042|MID7048|MID7127|MID8042|MID8048|MID8127|MID9042|MID9740|MID9742|MID7022|MID7010', + // http://www.match.net.cn/products.asp + 'MIDTablet' => 'M9701|M9000|M9100|M806|M1052|M806|T703|MID701|MID713|MID710|MID727|MID760|MID830|MID728|MID933|MID125|MID810|MID732|MID120|MID930|MID800|MID731|MID900|MID100|MID820|MID735|MID980|MID130|MID833|MID737|MID960|MID135|MID860|MID736|MID140|MID930|MID835|MID733|MID4X10', + // http://www.msi.com/support + // @todo Research the Windows Tablets. + 'MSITablet' => 'MSI \b(Primo 73K|Primo 73L|Primo 81L|Primo 77|Primo 93|Primo 75|Primo 76|Primo 73|Primo 81|Primo 91|Primo 90|Enjoy 71|Enjoy 7|Enjoy 10)\b', + // @todo http://www.kyoceramobile.com/support/drivers/ + // 'KyoceraTablet' => null, + // @todo http://intexuae.com/index.php/category/mobile-devices/tablets-products/ + // 'IntextTablet' => null, + // http://pdadb.net/index.php?m=pdalist&list=SMiT (NoName Chinese Tablets) + // http://www.imp3.net/14/show.php?itemid=20454 + 'SMiTTablet' => 'Android.*(\bMID\b|MID-560|MTV-T1200|MTV-PND531|MTV-P1101|MTV-PND530)', + // http://www.rock-chips.com/index.php?do=prod&pid=2 + 'RockChipTablet' => 'Android.*(RK2818|RK2808A|RK2918|RK3066)|RK2738|RK2808A', + // http://www.fly-phone.com/devices/tablets/ ; http://www.fly-phone.com/service/ + 'FlyTablet' => 'IQ310|Fly Vision', + // http://www.bqreaders.com/gb/tablets-prices-sale.html + 'bqTablet' => 'Android.*(bq)?.*(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant|Aquaris ([E|M]10|M8))|Maxwell.*Lite|Maxwell.*Plus', + // http://www.huaweidevice.com/worldwide/productFamily.do?method=index&directoryId=5011&treeId=3290 + // http://www.huaweidevice.com/worldwide/downloadCenter.do?method=index&directoryId=3372&treeId=0&tb=1&type=software (including legacy tablets) + 'HuaweiTablet' => 'MediaPad|MediaPad 7 Youth|IDEOS S7|S7-201c|S7-202u|S7-101|S7-103|S7-104|S7-105|S7-106|S7-201|S7-Slim|M2-A01L|BAH-L09|BAH-W09', + // Nec or Medias Tab + 'NecTablet' => '\bN-06D|\bN-08D', + // Pantech Tablets: http://www.pantechusa.com/phones/ + 'PantechTablet' => 'Pantech.*P4100', + // Broncho Tablets: http://www.broncho.cn/ (hard to find) + 'BronchoTablet' => 'Broncho.*(N701|N708|N802|a710)', + // http://versusuk.com/support.html + 'VersusTablet' => 'TOUCHPAD.*[78910]|\bTOUCHTAB\b', + // http://www.zync.in/index.php/our-products/tablet-phablets + 'ZyncTablet' => 'z1000|Z99 2G|z99|z930|z999|z990|z909|Z919|z900', + // http://www.positivoinformatica.com.br/www/pessoal/tablet-ypy/ + 'PositivoTablet' => 'TB07STA|TB10STA|TB07FTA|TB10FTA', + // https://www.nabitablet.com/ + 'NabiTablet' => 'Android.*\bNabi', + 'KoboTablet' => 'Kobo Touch|\bK080\b|\bVox\b Build|\bArc\b Build', + // French Danew Tablets http://www.danew.com/produits-tablette.php + 'DanewTablet' => 'DSlide.*\b(700|701R|702|703R|704|802|970|971|972|973|974|1010|1012)\b', + // Texet Tablets and Readers http://www.texet.ru/tablet/ + 'TexetTablet' => 'NaviPad|TB-772A|TM-7045|TM-7055|TM-9750|TM-7016|TM-7024|TM-7026|TM-7041|TM-7043|TM-7047|TM-8041|TM-9741|TM-9747|TM-9748|TM-9751|TM-7022|TM-7021|TM-7020|TM-7011|TM-7010|TM-7023|TM-7025|TM-7037W|TM-7038W|TM-7027W|TM-9720|TM-9725|TM-9737W|TM-1020|TM-9738W|TM-9740|TM-9743W|TB-807A|TB-771A|TB-727A|TB-725A|TB-719A|TB-823A|TB-805A|TB-723A|TB-715A|TB-707A|TB-705A|TB-709A|TB-711A|TB-890HD|TB-880HD|TB-790HD|TB-780HD|TB-770HD|TB-721HD|TB-710HD|TB-434HD|TB-860HD|TB-840HD|TB-760HD|TB-750HD|TB-740HD|TB-730HD|TB-722HD|TB-720HD|TB-700HD|TB-500HD|TB-470HD|TB-431HD|TB-430HD|TB-506|TB-504|TB-446|TB-436|TB-416|TB-146SE|TB-126SE', + // Avoid detecting 'PLAYSTATION 3' as mobile. + 'PlaystationTablet' => 'Playstation.*(Portable|Vita)', + // http://www.trekstor.de/surftabs.html + 'TrekstorTablet' => 'ST10416-1|VT10416-1|ST70408-1|ST702xx-1|ST702xx-2|ST80208|ST97216|ST70104-2|VT10416-2|ST10216-2A|SurfTab', + // http://www.pyleaudio.com/Products.aspx?%2fproducts%2fPersonal-Electronics%2fTablets + 'PyleAudioTablet' => '\b(PTBL10CEU|PTBL10C|PTBL72BC|PTBL72BCEU|PTBL7CEU|PTBL7C|PTBL92BC|PTBL92BCEU|PTBL9CEU|PTBL9CUK|PTBL9C)\b', + // http://www.advandigital.com/index.php?link=content-product&jns=JP001 + // because of the short codenames we have to include whitespaces to reduce the possible conflicts. + 'AdvanTablet' => 'Android.* \b(E3A|T3X|T5C|T5B|T3E|T3C|T3B|T1J|T1F|T2A|T1H|T1i|E1C|T1-E|T5-A|T4|E1-B|T2Ci|T1-B|T1-D|O1-A|E1-A|T1-A|T3A|T4i)\b ', + // http://www.danytech.com/category/tablet-pc + 'DanyTechTablet' => 'Genius Tab G3|Genius Tab S2|Genius Tab Q3|Genius Tab G4|Genius Tab Q4|Genius Tab G-II|Genius TAB GII|Genius TAB GIII|Genius Tab S1', + // http://www.galapad.net/product.html + 'GalapadTablet' => 'Android.*\bG1\b', + // http://www.micromaxinfo.com/tablet/funbook + 'MicromaxTablet' => 'Funbook|Micromax.*\b(P250|P560|P360|P362|P600|P300|P350|P500|P275)\b', + // http://www.karbonnmobiles.com/products_tablet.php + 'KarbonnTablet' => 'Android.*\b(A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2)\b', + // http://www.myallfine.com/Products.asp + 'AllFineTablet' => 'Fine7 Genius|Fine7 Shine|Fine7 Air|Fine8 Style|Fine9 More|Fine10 Joy|Fine11 Wide', + // http://www.proscanvideo.com/products-search.asp?itemClass=TABLET&itemnmbr= + 'PROSCANTablet' => '\b(PEM63|PLT1023G|PLT1041|PLT1044|PLT1044G|PLT1091|PLT4311|PLT4311PL|PLT4315|PLT7030|PLT7033|PLT7033D|PLT7035|PLT7035D|PLT7044K|PLT7045K|PLT7045KB|PLT7071KG|PLT7072|PLT7223G|PLT7225G|PLT7777G|PLT7810K|PLT7849G|PLT7851G|PLT7852G|PLT8015|PLT8031|PLT8034|PLT8036|PLT8080K|PLT8082|PLT8088|PLT8223G|PLT8234G|PLT8235G|PLT8816K|PLT9011|PLT9045K|PLT9233G|PLT9735|PLT9760G|PLT9770G)\b', + // http://www.yonesnav.com/products/products.php + 'YONESTablet' => 'BQ1078|BC1003|BC1077|RK9702|BC9730|BC9001|IT9001|BC7008|BC7010|BC708|BC728|BC7012|BC7030|BC7027|BC7026', + // http://www.cjshowroom.com/eproducts.aspx?classcode=004001001 + // China manufacturer makes tablets for different small brands (eg. http://www.zeepad.net/index.html) + 'ChangJiaTablet' => 'TPC7102|TPC7103|TPC7105|TPC7106|TPC7107|TPC7201|TPC7203|TPC7205|TPC7210|TPC7708|TPC7709|TPC7712|TPC7110|TPC8101|TPC8103|TPC8105|TPC8106|TPC8203|TPC8205|TPC8503|TPC9106|TPC9701|TPC97101|TPC97103|TPC97105|TPC97106|TPC97111|TPC97113|TPC97203|TPC97603|TPC97809|TPC97205|TPC10101|TPC10103|TPC10106|TPC10111|TPC10203|TPC10205|TPC10503', + // http://www.gloryunion.cn/products.asp + // http://www.allwinnertech.com/en/apply/mobile.html + // http://www.ptcl.com.pk/pd_content.php?pd_id=284 (EVOTAB) + // @todo: Softwiner tablets? + // aka. Cute or Cool tablets. Not sure yet, must research to avoid collisions. + 'GUTablet' => 'TX-A1301|TX-M9002|Q702|kf026', + // A12R|D75A|D77|D79|R83|A95|A106C|R15|A75|A76|D71|D72|R71|R73|R77|D82|R85|D92|A97|D92|R91|A10F|A77F|W71F|A78F|W78F|W81F|A97F|W91F|W97F|R16G|C72|C73E|K72|K73|R96G + // http://www.pointofview-online.com/showroom.php?shop_mode=product_listing&category_id=118 + 'PointOfViewTablet' => 'TAB-P506|TAB-navi-7-3G-M|TAB-P517|TAB-P-527|TAB-P701|TAB-P703|TAB-P721|TAB-P731N|TAB-P741|TAB-P825|TAB-P905|TAB-P925|TAB-PR945|TAB-PL1015|TAB-P1025|TAB-PI1045|TAB-P1325|TAB-PROTAB[0-9]+|TAB-PROTAB25|TAB-PROTAB26|TAB-PROTAB27|TAB-PROTAB26XL|TAB-PROTAB2-IPS9|TAB-PROTAB30-IPS9|TAB-PROTAB25XXL|TAB-PROTAB26-IPS10|TAB-PROTAB30-IPS10', + // http://www.overmax.pl/pl/katalog-produktow,p8/tablety,c14/ + // @todo: add more tests. + 'OvermaxTablet' => 'OV-(SteelCore|NewBase|Basecore|Baseone|Exellen|Quattor|EduTab|Solution|ACTION|BasicTab|TeddyTab|MagicTab|Stream|TB-08|TB-09)|Qualcore 1027', + // http://hclmetablet.com/India/index.php + 'HCLTablet' => 'HCL.*Tablet|Connect-3G-2.0|Connect-2G-2.0|ME Tablet U1|ME Tablet U2|ME Tablet G1|ME Tablet X1|ME Tablet Y2|ME Tablet Sync', + // http://www.edigital.hu/Tablet_es_e-book_olvaso/Tablet-c18385.html + 'DPSTablet' => 'DPS Dream 9|DPS Dual 7', + // http://www.visture.com/index.asp + 'VistureTablet' => 'V97 HD|i75 3G|Visture V4( HD)?|Visture V5( HD)?|Visture V10', + // http://www.mijncresta.nl/tablet + 'CrestaTablet' => 'CTP(-)?810|CTP(-)?818|CTP(-)?828|CTP(-)?838|CTP(-)?888|CTP(-)?978|CTP(-)?980|CTP(-)?987|CTP(-)?988|CTP(-)?989', + // MediaTek - http://www.mediatek.com/_en/01_products/02_proSys.php?cata_sn=1&cata1_sn=1&cata2_sn=309 + 'MediatekTablet' => '\bMT8125|MT8389|MT8135|MT8377\b', + // Concorde tab + 'ConcordeTablet' => 'Concorde([ ]+)?Tab|ConCorde ReadMan', + // GoClever Tablets - http://www.goclever.com/uk/products,c1/tablet,c5/ + 'GoCleverTablet' => 'GOCLEVER TAB|A7GOCLEVER|M1042|M7841|M742|R1042BK|R1041|TAB A975|TAB A7842|TAB A741|TAB A741L|TAB M723G|TAB M721|TAB A1021|TAB I921|TAB R721|TAB I720|TAB T76|TAB R70|TAB R76.2|TAB R106|TAB R83.2|TAB M813G|TAB I721|GCTA722|TAB I70|TAB I71|TAB S73|TAB R73|TAB R74|TAB R93|TAB R75|TAB R76.1|TAB A73|TAB A93|TAB A93.2|TAB T72|TAB R83|TAB R974|TAB R973|TAB A101|TAB A103|TAB A104|TAB A104.2|R105BK|M713G|A972BK|TAB A971|TAB R974.2|TAB R104|TAB R83.3|TAB A1042', + // Modecom Tablets - http://www.modecom.eu/tablets/portal/ + 'ModecomTablet' => 'FreeTAB 9000|FreeTAB 7.4|FreeTAB 7004|FreeTAB 7800|FreeTAB 2096|FreeTAB 7.5|FreeTAB 1014|FreeTAB 1001 |FreeTAB 8001|FreeTAB 9706|FreeTAB 9702|FreeTAB 7003|FreeTAB 7002|FreeTAB 1002|FreeTAB 7801|FreeTAB 1331|FreeTAB 1004|FreeTAB 8002|FreeTAB 8014|FreeTAB 9704|FreeTAB 1003', + // Vonino Tablets - http://www.vonino.eu/tablets + 'VoninoTablet' => '\b(Argus[ _]?S|Diamond[ _]?79HD|Emerald[ _]?78E|Luna[ _]?70C|Onyx[ _]?S|Onyx[ _]?Z|Orin[ _]?HD|Orin[ _]?S|Otis[ _]?S|SpeedStar[ _]?S|Magnet[ _]?M9|Primus[ _]?94[ _]?3G|Primus[ _]?94HD|Primus[ _]?QS|Android.*\bQ8\b|Sirius[ _]?EVO[ _]?QS|Sirius[ _]?QS|Spirit[ _]?S)\b', + // ECS Tablets - http://www.ecs.com.tw/ECSWebSite/Product/Product_Tablet_List.aspx?CategoryID=14&MenuID=107&childid=M_107&LanID=0 + 'ECSTablet' => 'V07OT2|TM105A|S10OT1|TR10CS1', + // Storex Tablets - http://storex.fr/espace_client/support.html + // @note: no need to add all the tablet codes since they are guided by the first regex. + 'StorexTablet' => 'eZee[_\']?(Tab|Go)[0-9]+|TabLC7|Looney Tunes Tab', + // Generic Vodafone tablets. + 'VodafoneTablet' => 'SmartTab([ ]+)?[0-9]+|SmartTabII10|SmartTabII7|VF-1497', + // French tablets - Essentiel B http://www.boulanger.fr/tablette_tactile_e-book/tablette_tactile_essentiel_b/cl_68908.htm?multiChoiceToDelete=brand&mc_brand=essentielb + // Aka: http://www.essentielb.fr/ + 'EssentielBTablet' => 'Smart[ \']?TAB[ ]+?[0-9]+|Family[ \']?TAB2', + // Ross & Moor - http://ross-moor.ru/ + 'RossMoorTablet' => 'RM-790|RM-997|RMD-878G|RMD-974R|RMT-705A|RMT-701|RME-601|RMT-501|RMT-711', + // i-mobile http://product.i-mobilephone.com/Mobile_Device + 'iMobileTablet' => 'i-mobile i-note', + // http://www.tolino.de/de/vergleichen/ + 'TolinoTablet' => 'tolino tab [0-9.]+|tolino shine', + // AudioSonic - a Kmart brand + // http://www.kmart.com.au/webapp/wcs/stores/servlet/Search?langId=-1&storeId=10701&catalogId=10001&categoryId=193001&pageSize=72¤tPage=1&searchCategory=193001%2b4294965664&sortBy=p_MaxPrice%7c1 + 'AudioSonicTablet' => '\bC-22Q|T7-QC|T-17B|T-17P\b', + // AMPE Tablets - http://www.ampe.com.my/product-category/tablets/ + // @todo: add them gradually to avoid conflicts. + 'AMPETablet' => 'Android.* A78 ', + // Skk Mobile - http://skkmobile.com.ph/product_tablets.php + 'SkkTablet' => 'Android.* (SKYPAD|PHOENIX|CYCLOPS)', + // Tecno Mobile (only tablet) - http://www.tecno-mobile.com/index.php/product?filterby=smart&list_order=all&page=1 + 'TecnoTablet' => 'TECNO P9|TECNO DP8D', + // JXD (consoles & tablets) - http://jxd.hk/products.asp?selectclassid=009008&clsid=3 + 'JXDTablet' => 'Android.* \b(F3000|A3300|JXD5000|JXD3000|JXD2000|JXD300B|JXD300|S5800|S7800|S602b|S5110b|S7300|S5300|S602|S603|S5100|S5110|S601|S7100a|P3000F|P3000s|P101|P200s|P1000m|P200m|P9100|P1000s|S6600b|S908|P1000|P300|S18|S6600|S9100)\b', + // i-Joy tablets - http://www.i-joy.es/en/cat/products/tablets/ + 'iJoyTablet' => 'Tablet (Spirit 7|Essentia|Galatea|Fusion|Onix 7|Landa|Titan|Scooby|Deox|Stella|Themis|Argon|Unique 7|Sygnus|Hexen|Finity 7|Cream|Cream X2|Jade|Neon 7|Neron 7|Kandy|Scape|Saphyr 7|Rebel|Biox|Rebel|Rebel 8GB|Myst|Draco 7|Myst|Tab7-004|Myst|Tadeo Jones|Tablet Boing|Arrow|Draco Dual Cam|Aurix|Mint|Amity|Revolution|Finity 9|Neon 9|T9w|Amity 4GB Dual Cam|Stone 4GB|Stone 8GB|Andromeda|Silken|X2|Andromeda II|Halley|Flame|Saphyr 9,7|Touch 8|Planet|Triton|Unique 10|Hexen 10|Memphis 4GB|Memphis 8GB|Onix 10)', + // http://www.intracon.eu/tablet + 'FX2Tablet' => 'FX2 PAD7|FX2 PAD10', + // http://www.xoro.de/produkte/ + // @note: Might be the same brand with 'Simply tablets' + 'XoroTablet' => 'KidsPAD 701|PAD[ ]?712|PAD[ ]?714|PAD[ ]?716|PAD[ ]?717|PAD[ ]?718|PAD[ ]?720|PAD[ ]?721|PAD[ ]?722|PAD[ ]?790|PAD[ ]?792|PAD[ ]?900|PAD[ ]?9715D|PAD[ ]?9716DR|PAD[ ]?9718DR|PAD[ ]?9719QR|PAD[ ]?9720QR|TelePAD1030|Telepad1032|TelePAD730|TelePAD731|TelePAD732|TelePAD735Q|TelePAD830|TelePAD9730|TelePAD795|MegaPAD 1331|MegaPAD 1851|MegaPAD 2151', + // http://www1.viewsonic.com/products/computing/tablets/ + 'ViewsonicTablet' => 'ViewPad 10pi|ViewPad 10e|ViewPad 10s|ViewPad E72|ViewPad7|ViewPad E100|ViewPad 7e|ViewSonic VB733|VB100a', + // https://www.verizonwireless.com/tablets/verizon/ + 'VerizonTablet' => 'QTAQZ3|QTAIR7|QTAQTZ3|QTASUN1|QTASUN2|QTAXIA1', + // http://www.odys.de/web/internet-tablet_en.html + 'OdysTablet' => 'LOOX|XENO10|ODYS[ -](Space|EVO|Xpress|NOON)|\bXELIO\b|Xelio10Pro|XELIO7PHONETAB|XELIO10EXTREME|XELIOPT2|NEO_QUAD10', + // http://www.captiva-power.de/products.html#tablets-en + 'CaptivaTablet' => 'CAPTIVA PAD', + // IconBIT - http://www.iconbit.com/products/tablets/ + 'IconbitTablet' => 'NetTAB|NT-3702|NT-3702S|NT-3702S|NT-3603P|NT-3603P|NT-0704S|NT-0704S|NT-3805C|NT-3805C|NT-0806C|NT-0806C|NT-0909T|NT-0909T|NT-0907S|NT-0907S|NT-0902S|NT-0902S', + // http://www.teclast.com/topic.php?channelID=70&topicID=140&pid=63 + 'TeclastTablet' => 'T98 4G|\bP80\b|\bX90HD\b|X98 Air|X98 Air 3G|\bX89\b|P80 3G|\bX80h\b|P98 Air|\bX89HD\b|P98 3G|\bP90HD\b|P89 3G|X98 3G|\bP70h\b|P79HD 3G|G18d 3G|\bP79HD\b|\bP89s\b|\bA88\b|\bP10HD\b|\bP19HD\b|G18 3G|\bP78HD\b|\bA78\b|\bP75\b|G17s 3G|G17h 3G|\bP85t\b|\bP90\b|\bP11\b|\bP98t\b|\bP98HD\b|\bG18d\b|\bP85s\b|\bP11HD\b|\bP88s\b|\bA80HD\b|\bA80se\b|\bA10h\b|\bP89\b|\bP78s\b|\bG18\b|\bP85\b|\bA70h\b|\bA70\b|\bG17\b|\bP18\b|\bA80s\b|\bA11s\b|\bP88HD\b|\bA80h\b|\bP76s\b|\bP76h\b|\bP98\b|\bA10HD\b|\bP78\b|\bP88\b|\bA11\b|\bA10t\b|\bP76a\b|\bP76t\b|\bP76e\b|\bP85HD\b|\bP85a\b|\bP86\b|\bP75HD\b|\bP76v\b|\bA12\b|\bP75a\b|\bA15\b|\bP76Ti\b|\bP81HD\b|\bA10\b|\bT760VE\b|\bT720HD\b|\bP76\b|\bP73\b|\bP71\b|\bP72\b|\bT720SE\b|\bC520Ti\b|\bT760\b|\bT720VE\b|T720-3GE|T720-WiFi', + // Onda - http://www.onda-tablet.com/buy-android-onda.html?dir=desc&limit=all&order=price + 'OndaTablet' => '\b(V975i|Vi30|VX530|V701|Vi60|V701s|Vi50|V801s|V719|Vx610w|VX610W|V819i|Vi10|VX580W|Vi10|V711s|V813|V811|V820w|V820|Vi20|V711|VI30W|V712|V891w|V972|V819w|V820w|Vi60|V820w|V711|V813s|V801|V819|V975s|V801|V819|V819|V818|V811|V712|V975m|V101w|V961w|V812|V818|V971|V971s|V919|V989|V116w|V102w|V973|Vi40)\b[\s]+', + 'JaytechTablet' => 'TPC-PA762', + 'BlaupunktTablet' => 'Endeavour 800NG|Endeavour 1010', + // http://www.digma.ru/support/download/ + // @todo: Ebooks also (if requested) + 'DigmaTablet' => '\b(iDx10|iDx9|iDx8|iDx7|iDxD7|iDxD8|iDsQ8|iDsQ7|iDsQ8|iDsD10|iDnD7|3TS804H|iDsQ11|iDj7|iDs10)\b', + // http://www.evolioshop.com/ro/tablete-pc.html + // http://www.evolio.ro/support/downloads_static.html?cat=2 + // @todo: Research some more + 'EvolioTablet' => 'ARIA_Mini_wifi|Aria[ _]Mini|Evolio X10|Evolio X7|Evolio X8|\bEvotab\b|\bNeura\b', + // @todo http://www.lavamobiles.com/tablets-data-cards + 'LavaTablet' => 'QPAD E704|\bIvoryS\b|E-TAB IVORY|\bE-TAB\b', + // http://www.breezetablet.com/ + 'AocTablet' => 'MW0811|MW0812|MW0922|MTK8382|MW1031|MW0831|MW0821|MW0931|MW0712', + // http://www.mpmaneurope.com/en/products/internet-tablets-14/android-tablets-14/ + 'MpmanTablet' => 'MP11 OCTA|MP10 OCTA|MPQC1114|MPQC1004|MPQC994|MPQC974|MPQC973|MPQC804|MPQC784|MPQC780|\bMPG7\b|MPDCG75|MPDCG71|MPDC1006|MP101DC|MPDC9000|MPDC905|MPDC706HD|MPDC706|MPDC705|MPDC110|MPDC100|MPDC99|MPDC97|MPDC88|MPDC8|MPDC77|MP709|MID701|MID711|MID170|MPDC703|MPQC1010', + // https://www.celkonmobiles.com/?_a=categoryphones&sid=2 + 'CelkonTablet' => 'CT695|CT888|CT[\s]?910|CT7 Tab|CT9 Tab|CT3 Tab|CT2 Tab|CT1 Tab|C820|C720|\bCT-1\b', + // http://www.wolderelectronics.com/productos/manuales-y-guias-rapidas/categoria-2-miTab + 'WolderTablet' => 'miTab \b(DIAMOND|SPACE|BROOKLYN|NEO|FLY|MANHATTAN|FUNK|EVOLUTION|SKY|GOCAR|IRON|GENIUS|POP|MINT|EPSILON|BROADWAY|JUMP|HOP|LEGEND|NEW AGE|LINE|ADVANCE|FEEL|FOLLOW|LIKE|LINK|LIVE|THINK|FREEDOM|CHICAGO|CLEVELAND|BALTIMORE-GH|IOWA|BOSTON|SEATTLE|PHOENIX|DALLAS|IN 101|MasterChef)\b', + 'MediacomTablet' => 'M-MPI10C3G|M-SP10EG|M-SP10EGP|M-SP10HXAH|M-SP7HXAH|M-SP10HXBH|M-SP8HXAH|M-SP8MXA', + // http://www.mi.com/en + 'MiTablet' => '\bMI PAD\b|\bHM NOTE 1W\b', + // http://www.nbru.cn/index.html + 'NibiruTablet' => 'Nibiru M1|Nibiru Jupiter One', + // http://navroad.com/products/produkty/tablety/ + // http://navroad.com/products/produkty/tablety/ + 'NexoTablet' => 'NEXO NOVA|NEXO 10|NEXO AVIO|NEXO FREE|NEXO GO|NEXO EVO|NEXO 3G|NEXO SMART|NEXO KIDDO|NEXO MOBI', + // http://leader-online.com/new_site/product-category/tablets/ + // http://www.leader-online.net.au/List/Tablet + 'LeaderTablet' => 'TBLT10Q|TBLT10I|TBL-10WDKB|TBL-10WDKBO2013|TBL-W230V2|TBL-W450|TBL-W500|SV572|TBLT7I|TBA-AC7-8G|TBLT79|TBL-8W16|TBL-10W32|TBL-10WKB|TBL-W100', + // http://www.datawind.com/ubislate/ + 'UbislateTablet' => 'UbiSlate[\s]?7C', + // http://www.pocketbook-int.com/ru/support + 'PocketBookTablet' => 'Pocketbook', + // http://www.kocaso.com/product_tablet.html + 'KocasoTablet' => '\b(TB-1207)\b', + // http://global.hisense.com/product/asia/tablet/Sero7/201412/t20141215_91832.htm + 'HisenseTablet' => '\b(F5281|E2371)\b', + // http://www.tesco.com/direct/hudl/ + 'Hudl' => 'Hudl HT7S3|Hudl 2', + // http://www.telstra.com.au/home-phone/thub-2/ + 'TelstraTablet' => 'T-Hub2', + 'GenericTablet' => 'Android.*\b97D\b|Tablet(?!.*PC)|BNTV250A|MID-WCDMA|LogicPD Zoom2|\bA7EB\b|CatNova8|A1_07|CT704|CT1002|\bM721\b|rk30sdk|\bEVOTAB\b|M758A|ET904|ALUMIUM10|Smartfren Tab|Endeavour 1010|Tablet-PC-4|Tagi Tab|\bM6pro\b|CT1020W|arc 10HD|\bTP750\b|\bQTAQZ3\b|WVT101|TM1088|KT107', + ]; + + /** + * List of mobile Operating Systems. + * + * @var array + */ + protected static $operatingSystems = [ + 'AndroidOS' => 'Android', + 'BlackBerryOS' => 'blackberry|\bBB10\b|rim tablet os', + 'PalmOS' => 'PalmOS|avantgo|blazer|elaine|hiptop|palm|plucker|xiino', + 'SymbianOS' => 'Symbian|SymbOS|Series60|Series40|SYB-[0-9]+|\bS60\b', + // @reference: http://en.wikipedia.org/wiki/Windows_Mobile + 'WindowsMobileOS' => 'Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Window Mobile|Windows Phone [0-9.]+|WCE;', + // @reference: http://en.wikipedia.org/wiki/Windows_Phone + // http://wifeng.cn/?r=blog&a=view&id=106 + // http://nicksnettravels.builttoroam.com/post/2011/01/10/Bogus-Windows-Phone-7-User-Agent-String.aspx + // http://msdn.microsoft.com/library/ms537503.aspx + // https://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx + 'WindowsPhoneOS' => 'Windows Phone 10.0|Windows Phone 8.1|Windows Phone 8.0|Windows Phone OS|XBLWP7|ZuneWP7|Windows NT 6.[23]; ARM;', + 'iOS' => '\biPhone.*Mobile|\biPod|\biPad|AppleCoreMedia', + // http://en.wikipedia.org/wiki/MeeGo + // @todo: research MeeGo in UAs + 'MeeGoOS' => 'MeeGo', + // http://en.wikipedia.org/wiki/Maemo + // @todo: research Maemo in UAs + 'MaemoOS' => 'Maemo', + 'JavaOS' => 'J2ME/|\bMIDP\b|\bCLDC\b', // '|Java/' produces bug #135 + 'webOS' => 'webOS|hpwOS', + 'badaOS' => '\bBada\b', + 'BREWOS' => 'BREW', + ]; + + /** + * List of mobile User Agents. + * + * IMPORTANT: This is a list of only mobile browsers. + * Mobile Detect 2.x supports only mobile browsers, + * it was never designed to detect all browsers. + * The change will come in 2017 in the 3.x release for PHP7. + * + * @var array + */ + protected static $browsers = [ + //'Vivaldi' => 'Vivaldi', + // @reference: https://developers.google.com/chrome/mobile/docs/user-agent + 'Chrome' => '\bCrMo\b|CriOS|Android.*Chrome/[.0-9]* (Mobile)?', + 'Dolfin' => '\bDolfin\b', + 'Opera' => 'Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR/[0-9.]+|Coast/[0-9.]+', + 'Skyfire' => 'Skyfire', + 'Edge' => 'Mobile Safari/[.0-9]* Edge', + 'IE' => 'IEMobile|MSIEMobile', // |Trident/[.0-9]+ + 'Firefox' => 'fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile|FxiOS', + 'Bolt' => 'bolt', + 'TeaShark' => 'teashark', + 'Blazer' => 'Blazer', + // @reference: http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/OptimizingforSafarioniPhone/OptimizingforSafarioniPhone.html#//apple_ref/doc/uid/TP40006517-SW3 + 'Safari' => 'Version.*Mobile.*Safari|Safari.*Mobile|MobileSafari', + // http://en.wikipedia.org/wiki/Midori_(web_browser) + //'Midori' => 'midori', + //'Tizen' => 'Tizen', + 'WeChat' => '\bMicroMessenger\b', + 'UCBrowser' => 'UC.*Browser|UCWEB', + 'baiduboxapp' => 'baiduboxapp', + 'baidubrowser' => 'baidubrowser', + // https://github.com/serbanghita/Mobile-Detect/issues/7 + 'DiigoBrowser' => 'DiigoBrowser', + // http://www.puffinbrowser.com/index.php + 'Puffin' => 'Puffin', + // http://mercury-browser.com/index.html + 'Mercury' => '\bMercury\b', + // http://en.wikipedia.org/wiki/Obigo_Browser + 'ObigoBrowser' => 'Obigo', + // http://en.wikipedia.org/wiki/NetFront + 'NetFront' => 'NF-Browser', + // @reference: http://en.wikipedia.org/wiki/Minimo + // http://en.wikipedia.org/wiki/Vision_Mobile_Browser + 'GenericBrowser' => 'NokiaBrowser|OviBrowser|OneBrowser|TwonkyBeamBrowser|SEMC.*Browser|FlyFlow|Minimo|NetFront|Novarra-Vision|MQQBrowser|MicroMessenger', + // @reference: https://en.wikipedia.org/wiki/Pale_Moon_(web_browser) + 'PaleMoon' => 'Android.*PaleMoon|Mobile.*PaleMoon', + ]; + + /** + * Utilities. + * + * @var array + */ + protected static $utilities = [ + // Experimental. When a mobile device wants to switch to 'Desktop Mode'. + // http://scottcate.com/technology/windows-phone-8-ie10-desktop-or-mobile/ + // https://github.com/serbanghita/Mobile-Detect/issues/57#issuecomment-15024011 + // https://developers.facebook.com/docs/sharing/best-practices + 'Bot' => 'Googlebot|facebookexternalhit|AdsBot-Google|Google Keyword Suggestion|Facebot|YandexBot|YandexMobileBot|bingbot|ia_archiver|AhrefsBot|Ezooms|GSLFbot|WBSearchBot|Twitterbot|TweetmemeBot|Twikle|PaperLiBot|Wotbox|UnwindFetchor|Exabot|MJ12bot|YandexImages|TurnitinBot|Pingdom', + 'MobileBot' => 'Googlebot-Mobile|AdsBot-Google-Mobile|YahooSeeker/M1A1-R2D2', + 'DesktopMode' => 'WPDesktop', + 'TV' => 'SonyDTV|HbbTV', // experimental + 'WebKit' => '(webkit)[ /]([\w.]+)', + // @todo: Include JXD consoles. + 'Console' => '\b(Nintendo|Nintendo WiiU|Nintendo 3DS|Nintendo Switch|PLAYSTATION|Xbox)\b', + 'Watch' => 'SM-V700', + ]; + + /** + * All possible HTTP headers that represent the + * User-Agent string. + * + * @var array + */ + protected static $uaHttpHeaders = [ + // The default User-Agent string. + 'HTTP_USER_AGENT', + // Header can occur on devices using Opera Mini. + 'HTTP_X_OPERAMINI_PHONE_UA', + // Vodafone specific header: http://www.seoprinciple.com/mobile-web-community-still-angry-at-vodafone/24/ + 'HTTP_X_DEVICE_USER_AGENT', + 'HTTP_X_ORIGINAL_USER_AGENT', + 'HTTP_X_SKYFIRE_PHONE', + 'HTTP_X_BOLT_PHONE_UA', + 'HTTP_DEVICE_STOCK_UA', + 'HTTP_X_UCBROWSER_DEVICE_UA', + ]; + + /** + * The individual segments that could exist in a User-Agent string. VER refers to the regular + * expression defined in the constant self::VER. + * + * @var array + */ + protected static $properties = [ + + // Build + 'Mobile' => 'Mobile/[VER]', + 'Build' => 'Build/[VER]', + 'Version' => 'Version/[VER]', + 'VendorID' => 'VendorID/[VER]', + + // Devices + 'iPad' => 'iPad.*CPU[a-z ]+[VER]', + 'iPhone' => 'iPhone.*CPU[a-z ]+[VER]', + 'iPod' => 'iPod.*CPU[a-z ]+[VER]', + //'BlackBerry' => array('BlackBerry[VER]', 'BlackBerry [VER];'), + 'Kindle' => 'Kindle/[VER]', + + // Browser + 'Chrome' => ['Chrome/[VER]', 'CriOS/[VER]', 'CrMo/[VER]'], + 'Coast' => ['Coast/[VER]'], + 'Dolfin' => 'Dolfin/[VER]', + // @reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent/Firefox + 'Firefox' => ['Firefox/[VER]', 'FxiOS/[VER]'], + 'Fennec' => 'Fennec/[VER]', + // http://msdn.microsoft.com/en-us/library/ms537503(v=vs.85).aspx + // https://msdn.microsoft.com/en-us/library/ie/hh869301(v=vs.85).aspx + 'Edge' => 'Edge/[VER]', + 'IE' => ['IEMobile/[VER];', 'IEMobile [VER]', 'MSIE [VER];', 'Trident/[0-9.]+;.*rv:[VER]'], + // http://en.wikipedia.org/wiki/NetFront + 'NetFront' => 'NetFront/[VER]', + 'NokiaBrowser' => 'NokiaBrowser/[VER]', + 'Opera' => [' OPR/[VER]', 'Opera Mini/[VER]', 'Version/[VER]'], + 'Opera Mini' => 'Opera Mini/[VER]', + 'Opera Mobi' => 'Version/[VER]', + 'UCBrowser' => ['UCWEB[VER]', 'UC.*Browser/[VER]'], + 'MQQBrowser' => 'MQQBrowser/[VER]', + 'MicroMessenger' => 'MicroMessenger/[VER]', + 'baiduboxapp' => 'baiduboxapp/[VER]', + 'baidubrowser' => 'baidubrowser/[VER]', + 'SamsungBrowser' => 'SamsungBrowser/[VER]', + 'Iron' => 'Iron/[VER]', + // @note: Safari 7534.48.3 is actually Version 5.1. + // @note: On BlackBerry the Version is overwriten by the OS. + 'Safari' => ['Version/[VER]', 'Safari/[VER]'], + 'Skyfire' => 'Skyfire/[VER]', + 'Tizen' => 'Tizen/[VER]', + 'Webkit' => 'webkit[ /][VER]', + 'PaleMoon' => 'PaleMoon/[VER]', + + // Engine + 'Gecko' => 'Gecko/[VER]', + 'Trident' => 'Trident/[VER]', + 'Presto' => 'Presto/[VER]', + 'Goanna' => 'Goanna/[VER]', + + // OS + 'iOS' => ' \bi?OS\b [VER][ ;]{1}', + 'Android' => 'Android [VER]', + 'BlackBerry' => ['BlackBerry[\w]+/[VER]', 'BlackBerry.*Version/[VER]', 'Version/[VER]'], + 'BREW' => 'BREW [VER]', + 'Java' => 'Java/[VER]', + // @reference: http://windowsteamblog.com/windows_phone/b/wpdev/archive/2011/08/29/introducing-the-ie9-on-windows-phone-mango-user-agent-string.aspx + // @reference: http://en.wikipedia.org/wiki/Windows_NT#Releases + 'Windows Phone OS' => ['Windows Phone OS [VER]', 'Windows Phone [VER]'], + 'Windows Phone' => 'Windows Phone [VER]', + 'Windows CE' => 'Windows CE/[VER]', + // http://social.msdn.microsoft.com/Forums/en-US/windowsdeveloperpreviewgeneral/thread/6be392da-4d2f-41b4-8354-8dcee20c85cd + 'Windows NT' => 'Windows NT [VER]', + 'Symbian' => ['SymbianOS/[VER]', 'Symbian/[VER]'], + 'webOS' => ['webOS/[VER]', 'hpwOS/[VER];'], + ]; + + /** + * Construct an instance of this class. + * + * @param array $headers Specify the headers as injection. Should be PHP _SERVER flavored. + * If left empty, will use the global _SERVER['HTTP_*'] vars instead. + * @param string $userAgent Inject the User-Agent header. If null, will use HTTP_USER_AGENT + * from the $headers array instead. + */ + public function __construct( + array $headers = null, + $userAgent = null + ) + { + $this->setHttpHeaders($headers); + $this->setUserAgent($userAgent); + } + + /** + * Get the current script version. + * This is useful for the demo.php file, + * so people can check on what version they are testing + * for mobile devices. + * + * @return string The version number in semantic version format. + */ + public static function getScriptVersion() + { + return self::VERSION; + } + + /** + * Set the HTTP Headers. Must be PHP-flavored. This method will reset existing headers. + * + * @param array $httpHeaders The headers to set. If null, then using PHP's _SERVER to extract + * the headers. The default null is left for backwards compatibility. + */ + public function setHttpHeaders($httpHeaders = null) + { + // use global _SERVER if $httpHeaders aren't defined + if ( ! is_array($httpHeaders) || ! count($httpHeaders)) + { + $httpHeaders = $_SERVER; + } + + // clear existing headers + $this->httpHeaders = []; + + // Only save HTTP headers. In PHP land, that means only _SERVER vars that + // start with HTTP_. + foreach ($httpHeaders as $key => $value) + { + if (substr($key, 0, 5) === 'HTTP_') + { + $this->httpHeaders[$key] = $value; + } + } + + // In case we're dealing with CloudFront, we need to know. + $this->setCfHeaders($httpHeaders); + } + + /** + * Retrieves the HTTP headers. + * + * @return array + */ + public function getHttpHeaders() + { + return $this->httpHeaders; + } + + /** + * Retrieves a particular header. If it doesn't exist, no exception/error is caused. + * Simply null is returned. + * + * @param string $header The name of the header to retrieve. Can be HTTP compliant such as + * "User-Agent" or "X-Device-User-Agent" or can be php-esque with the + * all-caps, HTTP_ prefixed, underscore seperated awesomeness. + * + * @return string|null The value of the header. + */ + public function getHttpHeader($header) + { + // are we using PHP-flavored headers? + if (strpos($header, '_') === false) + { + $header = str_replace('-', '_', $header); + $header = strtoupper($header); + } + + // test the alternate, too + $altHeader = 'HTTP_' . $header; + + //Test both the regular and the HTTP_ prefix + if (isset($this->httpHeaders[$header])) + { + return $this->httpHeaders[$header]; + } + elseif (isset($this->httpHeaders[$altHeader])) + { + return $this->httpHeaders[$altHeader]; + } + + return null; + } + + public function getMobileHeaders() + { + return self::$mobileHeaders; + } + + /** + * Get all possible HTTP headers that + * can contain the User-Agent string. + * + * @return array List of HTTP headers. + */ + public function getUaHttpHeaders() + { + return self::$uaHttpHeaders; + } + + /** + * Set CloudFront headers + * http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/header-caching.html#header-caching-web-device + * + * @param array $cfHeaders List of HTTP headers + * + * @return boolean If there were CloudFront headers to be set + */ + public function setCfHeaders($cfHeaders = null) + { + // use global _SERVER if $cfHeaders aren't defined + if ( ! is_array($cfHeaders) || ! count($cfHeaders)) + { + $cfHeaders = $_SERVER; + } + + // clear existing headers + $this->cloudfrontHeaders = []; + + // Only save CLOUDFRONT headers. In PHP land, that means only _SERVER vars that + // start with cloudfront-. + $response = false; + foreach ($cfHeaders as $key => $value) + { + if (substr(strtolower($key), 0, 16) === 'http_cloudfront_') + { + $this->cloudfrontHeaders[strtoupper($key)] = $value; + $response = true; + } + } + + return $response; + } + + /** + * Retrieves the cloudfront headers. + * + * @return array + */ + public function getCfHeaders() + { + return $this->cloudfrontHeaders; + } + + /** + * @param string $userAgent + * + * @return string + */ + private function prepareUserAgent($userAgent) + { + $userAgent = trim($userAgent); + $userAgent = substr($userAgent, 0, 500); + + return $userAgent; + } + + /** + * Set the User-Agent to be used. + * + * @param string $userAgent The user agent string to set. + * + * @return string|null + */ + public function setUserAgent($userAgent = null) + { + // Invalidate cache due to #375 + $this->cache = []; + + if (false === empty($userAgent)) + { + return $this->userAgent = $this->prepareUserAgent($userAgent); + } + else + { + $this->userAgent = null; + foreach ($this->getUaHttpHeaders() as $altHeader) + { + if (false === empty($this->httpHeaders[$altHeader])) + { // @todo: should use getHttpHeader(), but it would be slow. (Serban) + $this->userAgent .= $this->httpHeaders[$altHeader] . " "; + } + } + + if ( ! empty($this->userAgent)) + { + return $this->userAgent = $this->prepareUserAgent($this->userAgent); + } + } + + if (count($this->getCfHeaders()) > 0) + { + return $this->userAgent = 'Amazon CloudFront'; + } + + return $this->userAgent = null; + } + + /** + * Retrieve the User-Agent. + * + * @return string|null The user agent if it's set. + */ + public function getUserAgent() + { + return $this->userAgent; + } + + /** + * Set the detection type. Must be one of self::DETECTION_TYPE_MOBILE or + * self::DETECTION_TYPE_EXTENDED. Otherwise, nothing is set. + * + * @deprecated since version 2.6.9 + * + * @param string $type The type. Must be a self::DETECTION_TYPE_* constant. The default + * parameter is null which will default to self::DETECTION_TYPE_MOBILE. + */ + public function setDetectionType($type = null) + { + if ($type === null) + { + $type = self::DETECTION_TYPE_MOBILE; + } + + if ($type !== self::DETECTION_TYPE_MOBILE && $type !== self::DETECTION_TYPE_EXTENDED) + { + return; + } + + $this->detectionType = $type; + } + + public function getMatchingRegex() + { + return $this->matchingRegex; + } + + public function getMatchesArray() + { + return $this->matchesArray; + } + + /** + * Retrieve the list of known phone devices. + * + * @return array List of phone devices. + */ + public static function getPhoneDevices() + { + return self::$phoneDevices; + } + + /** + * Retrieve the list of known tablet devices. + * + * @return array List of tablet devices. + */ + public static function getTabletDevices() + { + return self::$tabletDevices; + } + + /** + * Alias for getBrowsers() method. + * + * @return array List of user agents. + */ + public static function getUserAgents() + { + return self::getBrowsers(); + } + + /** + * Retrieve the list of known browsers. Specifically, the user agents. + * + * @return array List of browsers / user agents. + */ + public static function getBrowsers() + { + return self::$browsers; + } + + /** + * Retrieve the list of known utilities. + * + * @return array List of utilities. + */ + public static function getUtilities() + { + return self::$utilities; + } + + /** + * Method gets the mobile detection rules. This method is used for the magic methods $detect->is*(). + * + * @deprecated since version 2.6.9 + * + * @return array All the rules (but not extended). + */ + public static function getMobileDetectionRules() + { + static $rules; + + if ( ! $rules) + { + $rules = array_merge( + self::$phoneDevices, + self::$tabletDevices, + self::$operatingSystems, + self::$browsers + ); + } + + return $rules; + } + + /** + * Method gets the mobile detection rules + utilities. + * The reason this is separate is because utilities rules + * don't necessary imply mobile. This method is used inside + * the new $detect->is('stuff') method. + * + * @deprecated since version 2.6.9 + * + * @return array All the rules + extended. + */ + public function getMobileDetectionRulesExtended() + { + static $rules; + + if ( ! $rules) + { + // Merge all rules together. + $rules = array_merge( + self::$phoneDevices, + self::$tabletDevices, + self::$operatingSystems, + self::$browsers, + self::$utilities + ); + } + + return $rules; + } + + /** + * Retrieve the current set of rules. + * + * @deprecated since version 2.6.9 + * + * @return array + */ + public function getRules() + { + if ($this->detectionType == self::DETECTION_TYPE_EXTENDED) + { + return self::getMobileDetectionRulesExtended(); + } + else + { + return self::getMobileDetectionRules(); + } + } + + /** + * Retrieve the list of mobile operating systems. + * + * @return array The list of mobile operating systems. + */ + public static function getOperatingSystems() + { + return self::$operatingSystems; + } + + /** + * Check the HTTP headers for signs of mobile. + * This is the fastest mobile check possible; it's used + * inside isMobile() method. + * + * @return bool + */ + public function checkHttpHeadersForMobile() + { + + foreach ($this->getMobileHeaders() as $mobileHeader => $matchType) + { + if (isset($this->httpHeaders[$mobileHeader])) + { + if (is_array($matchType['matches'])) + { + foreach ($matchType['matches'] as $_match) + { + if (strpos($this->httpHeaders[$mobileHeader], $_match) !== false) + { + return true; + } + } + + return false; + } + else + { + return true; + } + } + } + + return false; + } + + /** + * Magic overloading method. + * + * @method boolean is[...]() + * @param string $name + * @param array $arguments + * + * @return mixed + * @throws BadMethodCallException when the method doesn't exist and doesn't start with 'is' + */ + public function __call($name, $arguments) + { + // make sure the name starts with 'is', otherwise + if (substr($name, 0, 2) !== 'is') + { + throw new BadMethodCallException("No such method exists: $name"); + } + + $this->setDetectionType(self::DETECTION_TYPE_MOBILE); + + $key = substr($name, 2); + + return $this->matchUAAgainstKey($key); + } + + /** + * Find a detection rule that matches the current User-agent. + * + * @param null $userAgent deprecated + * + * @return boolean + */ + protected function matchDetectionRulesAgainstUA($userAgent = null) + { + // Begin general search. + foreach ($this->getRules() as $_regex) + { + if (empty($_regex)) + { + continue; + } + + if ($this->match($_regex, $userAgent)) + { + return true; + } + } + + return false; + } + + /** + * Search for a certain key in the rules array. + * If the key is found then try to match the corresponding + * regex against the User-Agent. + * + * @param string $key + * + * @return boolean + */ + protected function matchUAAgainstKey($key) + { + // Make the keys lowercase so we can match: isIphone(), isiPhone(), isiphone(), etc. + $key = strtolower($key); + if (false === isset($this->cache[$key])) + { + + // change the keys to lower case + $_rules = array_change_key_case($this->getRules()); + + if (false === empty($_rules[$key])) + { + $this->cache[$key] = $this->match($_rules[$key]); + } + + if (false === isset($this->cache[$key])) + { + $this->cache[$key] = false; + } + } + + return $this->cache[$key]; + } + + /** + * Check if the device is mobile. + * Returns true if any type of mobile device detected, including special ones + * + * @param null $userAgent deprecated + * @param null $httpHeaders deprecated + * + * @return bool + */ + public function isMobile($userAgent = null, $httpHeaders = null) + { + + if ($httpHeaders) + { + $this->setHttpHeaders($httpHeaders); + } + + if ($userAgent) + { + $this->setUserAgent($userAgent); + } + + // Check specifically for cloudfront headers if the useragent === 'Amazon CloudFront' + if ($this->getUserAgent() === 'Amazon CloudFront') + { + $cfHeaders = $this->getCfHeaders(); + if (array_key_exists('HTTP_CLOUDFRONT_IS_MOBILE_VIEWER', $cfHeaders) && $cfHeaders['HTTP_CLOUDFRONT_IS_MOBILE_VIEWER'] === 'true') + { + return true; + } + } + + $this->setDetectionType(self::DETECTION_TYPE_MOBILE); + + if ($this->checkHttpHeadersForMobile()) + { + return true; + } + else + { + return $this->matchDetectionRulesAgainstUA(); + } + } + + /** + * Check if the device is a tablet. + * Return true if any type of tablet device is detected. + * + * @param string $userAgent deprecated + * @param array $httpHeaders deprecated + * + * @return bool + */ + public function isTablet($userAgent = null, $httpHeaders = null) + { + // Check specifically for cloudfront headers if the useragent === 'Amazon CloudFront' + if ($this->getUserAgent() === 'Amazon CloudFront') + { + $cfHeaders = $this->getCfHeaders(); + if (array_key_exists('HTTP_CLOUDFRONT_IS_TABLET_VIEWER', $cfHeaders) && $cfHeaders['HTTP_CLOUDFRONT_IS_TABLET_VIEWER'] === 'true') + { + return true; + } + } + + $this->setDetectionType(self::DETECTION_TYPE_MOBILE); + + foreach (self::$tabletDevices as $_regex) + { + if ($this->match($_regex, $userAgent)) + { + return true; + } + } + + return false; + } + + /** + * This method checks for a certain property in the + * userAgent. + * @todo: The httpHeaders part is not yet used. + * + * @param string $key + * @param string $userAgent deprecated + * @param string $httpHeaders deprecated + * + * @return bool|int|null + */ + public function is($key, $userAgent = null, $httpHeaders = null) + { + // Set the UA and HTTP headers only if needed (eg. batch mode). + if ($httpHeaders) + { + $this->setHttpHeaders($httpHeaders); + } + + if ($userAgent) + { + $this->setUserAgent($userAgent); + } + + $this->setDetectionType(self::DETECTION_TYPE_EXTENDED); + + return $this->matchUAAgainstKey($key); + } + + /** + * Some detection rules are relative (not standard), + * because of the diversity of devices, vendors and + * their conventions in representing the User-Agent or + * the HTTP headers. + * + * This method will be used to check custom regexes against + * the User-Agent string. + * + * @param $regex + * @param string $userAgent + * + * @return bool + * + * @todo: search in the HTTP headers too. + */ + public function match($regex, $userAgent = null) + { + $match = (bool) preg_match(sprintf('#%s#is', $regex), (false === empty($userAgent) ? $userAgent : $this->userAgent), $matches); + // If positive match is found, store the results for debug. + if ($match) + { + $this->matchingRegex = $regex; + $this->matchesArray = $matches; + } + + return $match; + } + + /** + * Get the properties array. + * + * @return array + */ + public static function getProperties() + { + return self::$properties; + } + + /** + * Prepare the version number. + * + * @todo Remove the error supression from str_replace() call. + * + * @param string $ver The string version, like "2.6.21.2152"; + * + * @return float + */ + public function prepareVersionNo($ver) + { + $ver = str_replace(['_', ' ', '/'], '.', $ver); + $arrVer = explode('.', $ver, 2); + + if (isset($arrVer[1])) + { + $arrVer[1] = @str_replace('.', '', $arrVer[1]); // @todo: treat strings versions. + } + + return (float) implode('.', $arrVer); + } + + /** + * Check the version of the given property in the User-Agent. + * Will return a float number. (eg. 2_0 will return 2.0, 4.3.1 will return 4.31) + * + * @param string $propertyName The name of the property. See self::getProperties() array + * keys for all possible properties. + * @param string $type Either self::VERSION_TYPE_STRING to get a string value or + * self::VERSION_TYPE_FLOAT indicating a float value. This parameter + * is optional and defaults to self::VERSION_TYPE_STRING. Passing an + * invalid parameter will default to the this type as well. + * + * @return string|float The version of the property we are trying to extract. + */ + public function version($propertyName, $type = self::VERSION_TYPE_STRING) + { + if (empty($propertyName)) + { + return false; + } + + // set the $type to the default if we don't recognize the type + if ($type !== self::VERSION_TYPE_STRING && $type !== self::VERSION_TYPE_FLOAT) + { + $type = self::VERSION_TYPE_STRING; + } + + $properties = self::getProperties(); + + // Check if the property exists in the properties array. + if (true === isset($properties[$propertyName])) + { + + // Prepare the pattern to be matched. + // Make sure we always deal with an array (string is converted). + $properties[$propertyName] = (array) $properties[$propertyName]; + + foreach ($properties[$propertyName] as $propertyMatchString) + { + + $propertyPattern = str_replace('[VER]', self::VER, $propertyMatchString); + + // Identify and extract the version. + preg_match(sprintf('#%s#is', $propertyPattern), $this->userAgent, $match); + + if (false === empty($match[1])) + { + $version = ($type == self::VERSION_TYPE_FLOAT ? $this->prepareVersionNo($match[1]) : $match[1]); + + return $version; + } + } + } + + return false; + } + + /** + * Retrieve the mobile grading, using self::MOBILE_GRADE_* constants. + * + * @return string One of the self::MOBILE_GRADE_* constants. + */ + public function mobileGrade() + { + $isMobile = $this->isMobile(); + + if ( + // Apple iOS 4-7.0 – Tested on the original iPad (4.3 / 5.0), iPad 2 (4.3 / 5.1 / 6.1), iPad 3 (5.1 / 6.0), iPad Mini (6.1), iPad Retina (7.0), iPhone 3GS (4.3), iPhone 4 (4.3 / 5.1), iPhone 4S (5.1 / 6.0), iPhone 5 (6.0), and iPhone 5S (7.0) + $this->is('iOS') && $this->version('iPad', self::VERSION_TYPE_FLOAT) >= 4.3 || + $this->is('iOS') && $this->version('iPhone', self::VERSION_TYPE_FLOAT) >= 4.3 || + $this->is('iOS') && $this->version('iPod', self::VERSION_TYPE_FLOAT) >= 4.3 || + + // Android 2.1-2.3 - Tested on the HTC Incredible (2.2), original Droid (2.2), HTC Aria (2.1), Google Nexus S (2.3). Functional on 1.5 & 1.6 but performance may be sluggish, tested on Google G1 (1.5) + // Android 3.1 (Honeycomb) - Tested on the Samsung Galaxy Tab 10.1 and Motorola XOOM + // Android 4.0 (ICS) - Tested on a Galaxy Nexus. Note: transition performance can be poor on upgraded devices + // Android 4.1 (Jelly Bean) - Tested on a Galaxy Nexus and Galaxy 7 + ($this->version('Android', self::VERSION_TYPE_FLOAT) > 2.1 && $this->is('Webkit')) || + + // Windows Phone 7.5-8 - Tested on the HTC Surround (7.5), HTC Trophy (7.5), LG-E900 (7.5), Nokia 800 (7.8), HTC Mazaa (7.8), Nokia Lumia 520 (8), Nokia Lumia 920 (8), HTC 8x (8) + $this->version('Windows Phone OS', self::VERSION_TYPE_FLOAT) >= 7.5 || + + // Tested on the Torch 9800 (6) and Style 9670 (6), BlackBerry® Torch 9810 (7), BlackBerry Z10 (10) + $this->is('BlackBerry') && $this->version('BlackBerry', self::VERSION_TYPE_FLOAT) >= 6.0 || + // Blackberry Playbook (1.0-2.0) - Tested on PlayBook + $this->match('Playbook.*Tablet') || + + // Palm WebOS (1.4-3.0) - Tested on the Palm Pixi (1.4), Pre (1.4), Pre 2 (2.0), HP TouchPad (3.0) + ($this->version('webOS', self::VERSION_TYPE_FLOAT) >= 1.4 && $this->match('Palm|Pre|Pixi')) || + // Palm WebOS 3.0 - Tested on HP TouchPad + $this->match('hp.*TouchPad') || + + // Firefox Mobile 18 - Tested on Android 2.3 and 4.1 devices + ($this->is('Firefox') && $this->version('Firefox', self::VERSION_TYPE_FLOAT) >= 18) || + + // Chrome for Android - Tested on Android 4.0, 4.1 device + ($this->is('Chrome') && $this->is('AndroidOS') && $this->version('Android', self::VERSION_TYPE_FLOAT) >= 4.0) || + + // Skyfire 4.1 - Tested on Android 2.3 device + ($this->is('Skyfire') && $this->version('Skyfire', self::VERSION_TYPE_FLOAT) >= 4.1 && $this->is('AndroidOS') && $this->version('Android', self::VERSION_TYPE_FLOAT) >= 2.3) || + + // Opera Mobile 11.5-12: Tested on Android 2.3 + ($this->is('Opera') && $this->version('Opera Mobi', self::VERSION_TYPE_FLOAT) >= 11.5 && $this->is('AndroidOS')) || + + // Meego 1.2 - Tested on Nokia 950 and N9 + $this->is('MeeGoOS') || + + // Tizen (pre-release) - Tested on early hardware + $this->is('Tizen') || + + // Samsung Bada 2.0 - Tested on a Samsung Wave 3, Dolphin browser + // @todo: more tests here! + $this->is('Dolfin') && $this->version('Bada', self::VERSION_TYPE_FLOAT) >= 2.0 || + + // UC Browser - Tested on Android 2.3 device + (($this->is('UC Browser') || $this->is('Dolfin')) && $this->version('Android', self::VERSION_TYPE_FLOAT) >= 2.3) || + + // Kindle 3 and Fire - Tested on the built-in WebKit browser for each + ($this->match('Kindle Fire') || + $this->is('Kindle') && $this->version('Kindle', self::VERSION_TYPE_FLOAT) >= 3.0) || + + // Nook Color 1.4.1 - Tested on original Nook Color, not Nook Tablet + $this->is('AndroidOS') && $this->is('NookTablet') || + + // Chrome Desktop 16-24 - Tested on OS X 10.7 and Windows 7 + $this->version('Chrome', self::VERSION_TYPE_FLOAT) >= 16 && ! $isMobile || + + // Safari Desktop 5-6 - Tested on OS X 10.7 and Windows 7 + $this->version('Safari', self::VERSION_TYPE_FLOAT) >= 5.0 && ! $isMobile || + + // Firefox Desktop 10-18 - Tested on OS X 10.7 and Windows 7 + $this->version('Firefox', self::VERSION_TYPE_FLOAT) >= 10.0 && ! $isMobile || + + // Internet Explorer 7-9 - Tested on Windows XP, Vista and 7 + $this->version('IE', self::VERSION_TYPE_FLOAT) >= 7.0 && ! $isMobile || + + // Opera Desktop 10-12 - Tested on OS X 10.7 and Windows 7 + $this->version('Opera', self::VERSION_TYPE_FLOAT) >= 10 && ! $isMobile + ) + { + return self::MOBILE_GRADE_A; + } + + if ( + $this->is('iOS') && $this->version('iPad', self::VERSION_TYPE_FLOAT) < 4.3 || + $this->is('iOS') && $this->version('iPhone', self::VERSION_TYPE_FLOAT) < 4.3 || + $this->is('iOS') && $this->version('iPod', self::VERSION_TYPE_FLOAT) < 4.3 || + + // Blackberry 5.0: Tested on the Storm 2 9550, Bold 9770 + $this->is('Blackberry') && $this->version('BlackBerry', self::VERSION_TYPE_FLOAT) >= 5 && $this->version('BlackBerry', self::VERSION_TYPE_FLOAT) < 6 || + + //Opera Mini (5.0-6.5) - Tested on iOS 3.2/4.3 and Android 2.3 + ($this->version('Opera Mini', self::VERSION_TYPE_FLOAT) >= 5.0 && $this->version('Opera Mini', self::VERSION_TYPE_FLOAT) <= 7.0 && + ($this->version('Android', self::VERSION_TYPE_FLOAT) >= 2.3 || $this->is('iOS'))) || + + // Nokia Symbian^3 - Tested on Nokia N8 (Symbian^3), C7 (Symbian^3), also works on N97 (Symbian^1) + $this->match('NokiaN8|NokiaC7|N97.*Series60|Symbian/3') || + + // @todo: report this (tested on Nokia N71) + $this->version('Opera Mobi', self::VERSION_TYPE_FLOAT) >= 11 && $this->is('SymbianOS') + ) + { + return self::MOBILE_GRADE_B; + } + + if ( + // Blackberry 4.x - Tested on the Curve 8330 + $this->version('BlackBerry', self::VERSION_TYPE_FLOAT) <= 5.0 || + // Windows Mobile - Tested on the HTC Leo (WinMo 5.2) + $this->match('MSIEMobile|Windows CE.*Mobile') || $this->version('Windows Mobile', self::VERSION_TYPE_FLOAT) <= 5.2 || + + // Tested on original iPhone (3.1), iPhone 3 (3.2) + $this->is('iOS') && $this->version('iPad', self::VERSION_TYPE_FLOAT) <= 3.2 || + $this->is('iOS') && $this->version('iPhone', self::VERSION_TYPE_FLOAT) <= 3.2 || + $this->is('iOS') && $this->version('iPod', self::VERSION_TYPE_FLOAT) <= 3.2 || + + // Internet Explorer 7 and older - Tested on Windows XP + $this->version('IE', self::VERSION_TYPE_FLOAT) <= 7.0 && ! $isMobile + ) + { + return self::MOBILE_GRADE_C; + } + + // All older smartphone platforms and featurephones - Any device that doesn't support media queries + // will receive the basic, C grade experience. + return self::MOBILE_GRADE_C; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/src/Parameters.php b/deployed/regularlabs/libraries/regularlabs/src/Parameters.php new file mode 100644 index 00000000..886bc9c5 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/src/Parameters.php @@ -0,0 +1,377 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Library; + +defined('_JEXEC') or die; + +use JFile; +use Joomla\CMS\Component\ComponentHelper as JComponentHelper; +use Joomla\CMS\Plugin\PluginHelper as JPluginHelper; + +jimport('joomla.filesystem.file'); + +/** + * Class Parameters + * @package RegularLabs\Library + */ +class Parameters +{ + public static $instance = null; + + /** + * @return static instance + */ + public static function getInstance() + { + if (is_null(self::$instance)) + { + self::$instance = new static; + } + + return self::$instance; + } + + /** + * Get a usable parameter object based on the Joomla Registry object + * The object will have all the available parameters with their value (default value if none is set) + * + * @param \Registry $params + * @param string $path + * @param string $default + * + * @return object + */ + public function getParams($params, $path = '', $default = '', $use_cache = true) + { + $cache_id = 'getParams_' . json_encode($params) . '_' . $path . '_' . $default; + + if ($use_cache && Cache::has($cache_id)) + { + return Cache::get($cache_id); + } + + $xml = $this->loadXML($path, $default); + + if (empty($params)) + { + return Cache::set( + $cache_id, + (object) $xml + ); + } + + if ( ! is_object($params)) + { + $params = json_decode($params); + if (is_null($xml)) + { + $xml = (object) []; + } + } + elseif (method_exists($params, 'toObject')) + { + $params = $params->toObject(); + } + + if ( ! $params) + { + return Cache::set( + $cache_id, + (object) $xml + ); + } + + if (empty($xml)) + { + return Cache::set( + $cache_id, + $params + ); + } + + foreach ($xml as $key => $val) + { + if (isset($params->{$key}) && $params->{$key} != '') + { + continue; + } + + $params->{$key} = $val; + } + + return Cache::set( + $cache_id, + $params + ); + } + + /** + * Get a usable parameter object for the component + * + * @param string $name + * @param \Registry $params + * + * @return object + */ + public function getComponentParams($name, $params = null, $use_cache = true) + { + $name = 'com_' . RegEx::replace('^com_', '', $name); + + $cache_id = 'getComponentParams_' . $name . '_' . json_encode($params); + + if ($use_cache && Cache::has($cache_id)) + { + return Cache::get($cache_id); + } + + if (empty($params) && JComponentHelper::isInstalled($name)) + { + $params = JComponentHelper::getParams($name); + } + + return Cache::set( + $cache_id, + $this->getParams($params, JPATH_ADMINISTRATOR . '/components/' . $name . '/config.xml') + ); + } + + /** + * Get a usable parameter object for the module + * + * @param string $name + * @param int $admin + * @param \Registry $params + * + * @return object + */ + public function getModuleParams($name, $admin = true, $params = '', $use_cache = true) + { + $name = 'mod_' . RegEx::replace('^mod_', '', $name); + + $cache_id = 'getModuleParams_' . $name . '_' . json_encode($params); + + if ($use_cache && Cache::has($cache_id)) + { + return Cache::get($cache_id); + } + + if (empty($params)) + { + $params = null; + } + + return Cache::set( + $cache_id, + $this->getParams($params, ($admin ? JPATH_ADMINISTRATOR : JPATH_SITE) . '/modules/' . $name . '/' . $name . '.xml') + ); + } + + /** + * Get a usable parameter object for the plugin + * + * @param string $name + * @param string $type + * @param \Registry $params + * + * @return object + */ + public function getPluginParams($name, $type = 'system', $params = '', $use_cache = true) + { + $cache_id = 'getPluginParams_' . $name . '_' . $type . '_' . json_encode($params); + + if ($use_cache && Cache::has($cache_id)) + { + return Cache::get($cache_id); + } + + if (empty($params)) + { + $plugin = JPluginHelper::getPlugin($type, $name); + $params = (is_object($plugin) && isset($plugin->params)) ? $plugin->params : null; + } + + return Cache::set( + $cache_id, + $this->getParams($params, JPATH_PLUGINS . '/' . $type . '/' . $name . '/' . $name . '.xml') + ); + } + + /** + * Returns an object based on the data in a given xml array + * + * @param $xml + * + * @return bool|mixed + */ + public function getObjectFromXml(&$xml, $use_cache = true) + { + $cache_id = 'getObjectFromXml_' . json_encode($xml); + + if ($use_cache && Cache::has($cache_id)) + { + return Cache::get($cache_id); + } + + if ( ! is_array($xml)) + { + $xml = [$xml]; + } + + $object = $this->getObjectFromXmlNode($xml); + + return Cache::set( + $cache_id, + $object + ); + } + + /** + * Returns an array based on the data in a given xml file + * + * @param string $path + * @param string $default + * + * @return array + */ + private function loadXML($path, $default = '', $use_cache = true) + { + $cache_id = 'loadXML_' . $path . '_' . $default; + + if ($use_cache && Cache::has($cache_id)) + { + return Cache::get($cache_id); + } + + if ( ! $path + || ! file_exists($path) + || ! $file = JFile::read($path) + ) + { + return Cache::set( + $cache_id, + [] + ); + } + + $xml = []; + + $xml_parser = xml_parser_create(); + xml_parse_into_struct($xml_parser, $file, $fields); + xml_parser_free($xml_parser); + + $default = $default ? strtoupper($default) : 'DEFAULT'; + foreach ($fields as $field) + { + if ($field['tag'] != 'FIELD' + || ! isset($field['attributes']) + || ( ! isset($field['attributes']['DEFAULT']) && ! isset($field['attributes'][$default])) + || ! isset($field['attributes']['NAME']) + || $field['attributes']['NAME'] == '' + || $field['attributes']['NAME'][0] == '@' + || ! isset($field['attributes']['TYPE']) + || $field['attributes']['TYPE'] == 'spacer' + ) + { + continue; + } + + if (isset($field['attributes'][$default])) + { + $field['attributes']['DEFAULT'] = $field['attributes'][$default]; + } + + if ($field['attributes']['TYPE'] == 'textarea') + { + $field['attributes']['DEFAULT'] = str_replace('
', "\n", $field['attributes']['DEFAULT']); + } + + $xml[$field['attributes']['NAME']] = $field['attributes']['DEFAULT']; + } + + return Cache::set( + $cache_id, + $xml + ); + } + + /** + * Returns the main attributes key from an xml object + * + * @param $xml + * + * @return mixed + */ + private function getKeyFromXML($xml) + { + if ( ! empty($xml->_attributes) && isset($xml->_attributes['name'])) + { + return $xml->_attributes['name']; + } + + return $xml->_name; + } + + /** + * Returns the value from an xml object / node + * + * @param $xml + * + * @return object + */ + private function getValFromXML($xml) + { + if ( ! empty($xml->_attributes) && isset($xml->_attributes['value'])) + { + return $xml->_attributes['value']; + } + + if (empty($xml->_children)) + { + return $xml->_data; + } + + return $this->getObjectFromXmlNode($xml->_children); + } + + /** + * Create an object from the given xml node + * + * @param $xml + * + * @return object + */ + private function getObjectFromXmlNode($xml) + { + $object = (object) []; + + foreach ($xml as $child) + { + $key = $this->getKeyFromXML($child); + $value = $this->getValFromXML($child); + + if ( ! isset($object->{$key})) + { + $object->{$key} = $value; + continue; + } + + if ( ! is_array($object->{$key})) + { + $object->{$key} = [$object->{$key}]; + } + + $object->{$key}[] = $value; + } + + return $object; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/src/PluginTag.php b/deployed/regularlabs/libraries/regularlabs/src/PluginTag.php new file mode 100644 index 00000000..eaa2380e --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/src/PluginTag.php @@ -0,0 +1,771 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Library; + +defined('_JEXEC') or die; + +/** + * Class PluginTag + * @package RegularLabs\Library + */ +class PluginTag +{ + /** + * @var array + */ + static $protected_characters = [ + '=' => '[[:EQUAL:]]', + '"' => '[[:QUOTE:]]', + ',' => '[[:COMMA:]]', + '|' => '[[:BAR:]]', + ':' => '[[:COLON:]]', + ]; + + /** + * Cleans the given tag word + * + * @param string $string + * + * @return string + */ + public static function clean($string = '') + { + return RegEx::replace('[^a-z0-9-_]', '', $string); + } + + /** + * Get the attributes from plugin style string + * + * @param string $string + * @param string $main_key + * @param array $known_boolean_keys + * @param array $keep_escaped_chars + * + * @return object + */ + public static function getAttributesFromString($string = '', $main_key = 'title', $known_boolean_keys = [], $keep_escaped_chars = [',']) + { + if (empty($string)) + { + return (object) []; + } + + // Replace html entity quotes to normal quotes + $string = str_replace('"', '"', $string); + + self::protectSpecialChars($string); + + // replace weird whitespace + $string = str_replace(chr(194) . chr(160), ' ', $string); + + // Replace html entity spaces between attributes to normal spaces + $string = RegEx::replace('((?:^|")\s*) (\s*(?:[a-z]|$))', '\1 \2', $string); + + // Only one value, so return simple key/value object + if (strpos($string, '|') == false && ! RegEx::match('=\s*"', $string)) + { + self::unprotectSpecialChars($string, $keep_escaped_chars); + + return (object) [$main_key => $string]; + } + + // No foo="bar" syntax found, so assume old syntax + if ( ! RegEx::match('=\s*"', $string)) + { + self::unprotectSpecialChars($string, $keep_escaped_chars); + + $attributes = self::getAttributesFromStringOld($string, [$main_key]); + self::convertOldSyntax($attributes, $known_boolean_keys); + + return $attributes; + } + + // Cannot find right syntax, so return simple key/value object + if ( ! RegEx::matchAll('(?:^|\s)(?[a-z0-9-_]+)\s*(?\!?)=\s*"(?.*?)"', $string, $matches)) + { + self::unprotectSpecialChars($string, $keep_escaped_chars); + + return (object) [$main_key => $string]; + } + + $tag = (object) []; + + foreach ($matches as $match) + { + $tag->{$match['key']} = self::getAttributeValueFromMatch($match, $known_boolean_keys, $keep_escaped_chars); + } + + return $tag; + } + + /** + * Get the value from a found attribute match + * + * @param array $match + * @param array $known_boolean_keys + * @param array $keep_escaped_chars + * + * @return bool|int|string + */ + private static function getAttributeValueFromMatch($match, $known_boolean_keys = [], $keep_escaped_chars = [',']) + { + $value = $match['value']; + + self::unprotectSpecialChars($value, $keep_escaped_chars); + + if (is_numeric($value) + && ( + in_array($match['key'], $known_boolean_keys) + || in_array(strtolower($match['key']), $known_boolean_keys) + ) + ) + { + $value = $value ? 'true' : 'false'; + } + + // Convert numeric values to ints/floats + if (is_numeric($value)) + { + $value = $value + 0; + } + + // Convert boolean values to actual booleans + switch ($value) + { + case 'true': + return $match['not'] ? false : true; + break; + + case 'false': + return $match['not'] ? true : false; + break; + + default: + return $match['not'] ? '!NOT!' . $value : $value; + break; + } + } + + /** + * Replace special characters in the string with the protected versions + * + * @param string $string + */ + public static function protectSpecialChars(&$string) + { + $unescaped_chars = array_keys(self::$protected_characters); + array_walk($unescaped_chars, function (&$char) { + $char = '\\' . $char; + }); + + // replace escaped characters with special markup + $string = str_replace( + $unescaped_chars, + array_values(self::$protected_characters), + $string + ); + + if ( ! RegEx::matchAll( + '(<.*?>|{.*?}|\[.*?\])', + $string, + $tags, + null, + PREG_PATTERN_ORDER + ) + ) + { + return; + } + + foreach ($tags[0] as $tag) + { + // replace unescaped characters with special markup + $protected = str_replace( + ['=', '"'], + [self::$protected_characters['='], self::$protected_characters['"']], + $tag + ); + + $string = str_replace($tag, $protected, $string); + } + } + + /** + * Replace protected characters in the string with the original special versions + * + * @param string $string + * @param array $keep_escaped_chars + */ + public static function unprotectSpecialChars(&$string, $keep_escaped_chars = []) + { + $unescaped_chars = array_keys(self::$protected_characters); + + if ( ! empty($keep_escaped_chars)) + { + array_walk($unescaped_chars, function (&$char, $key, $keep_escaped_chars) { + if (is_array($keep_escaped_chars) && ! in_array($char, $keep_escaped_chars)) + { + return; + } + $char = '\\' . $char; + }, $keep_escaped_chars); + } + + // replace special markup with unescaped characters + $string = str_replace( + array_values(self::$protected_characters), + $unescaped_chars, + $string + ); + } + + /** + * Only used for old syntaxes + * + * @param string $string + * @param array $keys + * @param string $separator + * @param string $equal + * @param int $limit + * + * @return object + */ + public static function getAttributesFromStringOld($string = '', $keys = ['title'], $separator = '|', $equal = '=', $limit = 0) + { + $temp_separator = '[[SEPARATOR]]'; + $temp_equal = '[[EQUAL]]'; + $tag_start = '[[TAG]]'; + $tag_end = '[[/TAG]]'; + + // replace separators and equal signs with special markup + $string = str_replace([$separator, $equal], [$temp_separator, $temp_equal], $string); + // replace protected separators and equal signs back to original + $string = str_replace(['\\' . $temp_separator, '\\' . $temp_equal], [$separator, $equal], $string); + + // protect all html tags + RegEx::matchAll(']*>', $string, $tags); + + if ( ! empty($tags)) + { + foreach ($tags as $tag) + { + $string = str_replace( + $tag[0], + $tag_start . base64_encode(str_replace([$temp_separator, $temp_equal], [$separator, $equal], $tag[0])) . $tag_end, + $string + ); + } + } + + // split string into array + $attribs = $limit + ? explode($temp_separator, $string, (int) $limit) + : explode($temp_separator, $string); + + $attributes = (object) [ + 'params' => [], + ]; + + // loop through splits + foreach ($attribs as $i => $keyval) + { + // spit part into key and val by equal sign + $keyval = explode($temp_equal, $keyval, 2); + if (isset($keyval[1])) + { + $keyval[1] = str_replace([$temp_separator, $temp_equal], [$separator, $equal], $keyval[1]); + } + + // unprotect tags in key and val + foreach ($keyval as $key => $val) + { + RegEx::matchAll(RegEx::quote($tag_start) . '(.*?)' . RegEx::quote($tag_end), $val, $tags); + + if ( ! empty($tags)) + { + foreach ($tags as $tag) + { + $val = str_replace($tag[0], base64_decode($tag[1]), $val); + } + + $keyval[trim($key)] = $val; + } + } + + if (isset($keys[$i])) + { + $key = trim($keys[$i]); + // if value is in the keys array add as defined in keys array + // ignore equal sign + $val = implode($equal, $keyval); + if (substr($val, 0, strlen($key) + 1) == $key . '=') + { + $val = substr($val, strlen($key) + 1); + } + $attributes->{$key} = $val; + unset($keys[$i]); + + continue; + } + + // else add as defined in the string + if (isset($keyval[1])) + { + $attributes->{$keyval[0]} = $keyval[1]; + continue; + } + + $attributes->params[] = implode($equal, $keyval); + } + + return $attributes; + } + + /** + * Replace keys aliases with the main key names in an object + * + * @param object $attributes + * @param array $key_aliases + * @param bool $handle_plurals + */ + public static function replaceKeyAliases(&$attributes, $key_aliases = [], $handle_plurals = false) + { + foreach ($key_aliases as $key => $aliases) + { + if (self::replaceKeyAlias($attributes, $key, $key, $handle_plurals)) + { + continue; + } + + foreach ($aliases as $alias) + { + if ( ! isset($attributes->{$alias})) + { + continue; + } + + if (self::replaceKeyAlias($attributes, $key, $alias, $handle_plurals)) + { + break; + } + } + } + } + + /** + * Replace specific key alias with the main key name in an object + * + * @param object $attributes + * @param string $key + * @param string $alias + * @param bool $handle_plurals + * + * @return bool + */ + private static function replaceKeyAlias(&$attributes, $key, $alias, $handle_plurals = false) + { + if ($handle_plurals) + { + if (self::replaceKeyAlias($attributes, $key, $alias . 's')) + { + return true; + } + + if (substr($alias, -1) == 's' && self::replaceKeyAlias($attributes, $key, substr($alias, 0, -1))) + { + return true; + } + } + + if (isset($attributes->{$key})) + { + return true; + } + + if ( ! isset($attributes->{$alias})) + { + return false; + } + + $attributes->{$key} = $attributes->{$alias}; + unset($attributes->{$alias}); + + return true; + } + + /** + * Convert an object using the old param style to the new syntax + * + * @param object $attributes + * @param array $known_boolean_keys + * @param string $extra_key + */ + public static function convertOldSyntax(&$attributes, $known_boolean_keys = [], $extra_key = 'class') + { + $extra = isset($attributes->class) ? [$attributes->class] : []; + + foreach ($attributes->params as $i => $param) + { + if ( ! $param) + { + continue; + } + + if (in_array($param, $known_boolean_keys)) + { + $attributes->{$param} = true; + continue; + } + + if (strpos($param, '=') == false) + { + $extra[] = $param; + continue; + } + + list($key, $val) = explode('=', $param, 2); + + $attributes->{$key} = $val; + } + + $attributes->{$extra_key} = trim(implode(' ', $extra)); + + unset($attributes->params); + } + + /** + * Return the Regular Expressions string to match: + * Different types of spaces + * + * @param string $modifier + * + * @return string + */ + public static function getRegexSpaces($modifier = '+') + { + return '(?:\s| |&\#160;)' . $modifier; + } + + /** + * Return the Regular Expressions string to match: + * Plugin type tags inside others + * + * @return string + */ + public static function getRegexInsideTag() + { + return '(?:[^\{\}]*\{[^\}]*\})*.*?'; + } + + /** + * Return the Regular Expressions string to match: + * html before plugin tag + * + * @param string $group_id + * + * @return string + */ + public static function getRegexLeadingHtml($group_id = '') + { + $group = 'leading_block_element'; + $html_tag_group = 'html_tag'; + + if ($group_id) + { + $group .= '_' . $group_id; + $html_tag_group .= '_' . $group_id; + } + + $block_elements = Html::getBlockElements(['div']); + $block_element = '(?<' . $group . '>' . implode('|', $block_elements) . ')'; + + $other_html = '[^<]*(<(?<' . $html_tag_group . '>[a-z][a-z0-9_-]*)[\s>]([^<]*)?[^<]*)*'; + + // Grab starting block element tag and any html after it (that is not the same block element starting/ending tag). + return '(?:' + . '<' . $block_element . '(?: [^>]*)?>' + . $other_html + . ')?'; + } + + /** + * Return the Regular Expressions string to match: + * html after plugin tag + * + * @param string $group_id + * + * @return string + */ + public static function getRegexTrailingHtml($group_id = '') + { + $group = 'leading_block_element'; + + if ($group_id) + { + $group .= '_' . $group_id; + } + + // If the grouped name is found, then grab all content till ending html tag is found. Otherwise grab nothing. + return '(?(<' . $group . '>)' + . '(?:.*?)?' + . ')'; + } + + /** + * Return the Regular Expressions string to match: + * Opening html tags + * + * @param array $block_elements + * @param array $inline_elements + * @param array $excluded_block_elements + * + * @return string + */ + public static function getRegexSurroundingTagsPre($block_elements = [], $inline_elements = ['span'], $excluded_block_elements = []) + { + $block_elements = ! empty($block_elements) ? $block_elements : Html::getBlockElements($excluded_block_elements); + + $regex = '(?:<(?:' . implode('|', $block_elements) . ')(?: [^>]*)?>\s*(?:
\s*)*)?'; + + if ( ! empty($inline_elements)) + { + $regex .= '(?:<(?:' . implode('|', $inline_elements) . ')(?: [^>]*)?>\s*(?:
\s*)*){0,3}'; + } + + return $regex; + } + + /** + * Return the Regular Expressions string to match: + * Closing html tags + * + * @param array $block_elements + * @param array $inline_elements + * @param array $excluded_block_elements + * + * @return string + */ + public static function getRegexSurroundingTagsPost($block_elements = [], $inline_elements = ['span'], $excluded_block_elements = []) + { + $block_elements = ! empty($block_elements) ? $block_elements : Html::getBlockElements($excluded_block_elements); + + $regex = ''; + + if ( ! empty($inline_elements)) + { + $regex .= '(?:(?:\s*
)*\s*<\/(?:' . implode('|', $inline_elements) . ')>){0,3}'; + } + + $regex .= '(?:(?:\s*
)*\s*<\/(?:' . implode('|', $block_elements) . ')>)?'; + + return $regex; + } + + /** + * Return the Regular Expressions string to match: + * Leading html tag + * + * @param array $elements + * + * @return string + */ + public static function getRegexSurroundingTagPre($elements = []) + { + $elements = ! empty($elements) ? $elements : array_merge(Html::getBlockElements(), ['span']); + + return '(?:<(?:' . implode('|', $elements) . ')(?: [^>]*)?>\s*(?:
\s*)*)?'; + } + + /** + * Return the Regular Expressions string to match: + * Trailing html tag + * + * @param array $elements + * + * @return string + */ + public static function getRegexSurroundingTagPost($elements = []) + { + $elements = ! empty($elements) ? $elements : array_merge(Html::getBlockElements(), ['span']); + + return '(?:(?:\s*
)*\s*<\/(?:' . implode('|', $elements) . ')>)?'; + } + + /** + * Return the Regular Expressions string to match: + * Plugin style tags + * + * @param array $tags + * @param bool $include_no_attributes + * @param bool $include_ending + * @param array $required_attributes + * + * @return string + */ + public static function getRegexTags($tags, $include_no_attributes = true, $include_ending = true, $required_attributes = []) + { + $tags = ArrayHelper::toArray($tags); + $tags = count($tags) > 1 ? '(?:' . implode('|', $tags) . ')' : $tags[0]; + + $value = '(?:\s*=\s*(?:"[^"]*"|\'[^\']*\'|[a-z0-9-_]+))?'; + $attributes = '(?:\s+[a-z0-9-_]+' . $value . ')+'; + + $required_attributes = ArrayHelper::toArray($required_attributes); + if ( ! empty($required_attributes)) + { + $attributes = '(?:' . $attributes . ')?' . '(?:\s+' . implode('|', $required_attributes) . ')' . $value . '(?:' . $attributes . ')?'; + } + + if ($include_no_attributes) + { + $attributes = '\s*(?:' . $attributes . ')?'; + } + + if ( ! $include_ending) + { + return '<' . $tags . $attributes . '\s*/?>'; + } + + return '<(?:\/' . $tags . '|' . $tags . $attributes . '\s*/?)\s*/?>'; + } + + /** + * Extract the plugin style div tags with the possible attributes. like: + * {div width:100|float:left}...{/div} + * + * @param string $start_tag + * @param string $end_tag + * @param string $tag_start + * @param string $tag_end + * + * @return array + */ + public static function getDivTags($start_tag = '', $end_tag = '', $tag_start = '{', $tag_end = '}') + { + $tag_start = RegEx::quote($tag_start); + $tag_end = RegEx::quote($tag_end); + + $start_div = ['pre' => '', 'tag' => '', 'post' => '']; + $end_div = ['pre' => '', 'tag' => '', 'post' => '']; + + if ( ! empty($start_tag) + && RegEx::match( + '^(?
.*?)(?' . $tag_start . 'div(?: .*?)?' . $tag_end . ')(?.*)$',
+				$start_tag,
+				$match
+			)
+		)
+		{
+			$start_div = $match;
+		}
+
+		if ( ! empty($end_tag)
+			&& RegEx::match(
+				'^(?
.*?)(?' . $tag_start . '/div' . $tag_end . ')(?.*)$',
+				$end_tag,
+				$match
+			)
+		)
+		{
+			$end_div = $match;
+		}
+
+		if (empty($start_div['tag']) || empty($end_div['tag']))
+		{
+			return [$start_div, $end_div];
+		}
+
+		$attribs = trim(RegEx::replace($tag_start . 'div(.*)' . $tag_end, '\1', $start_div['tag']));
+
+		$start_div['tag'] = '
'; + $end_div['tag'] = '
'; + + if (empty($attribs)) + { + return [$start_div, $end_div]; + } + + $attribs = self::getDivAttributes($attribs); + + $style = []; + + if (isset($attribs->width)) + { + if (is_numeric($attribs->width)) + { + $attribs->width .= 'px'; + } + $style[] = 'width:' . $attribs->width; + } + + if (isset($attribs->height)) + { + if (is_numeric($attribs->height)) + { + $attribs->height .= 'px'; + } + $style[] = 'height:' . $attribs->height; + } + + if (isset($attribs->align)) + { + $style[] = 'float:' . $attribs->align; + } + + if ( ! isset($attribs->align) && isset($attribs->float)) + { + $style[] = 'float:' . $attribs->float; + } + + $attribs = isset($attribs->class) ? 'class="' . $attribs->class . '"' : ''; + + if ( ! empty($style)) + { + $attribs .= ' style="' . implode(';', $style) . ';"'; + } + + $start_div['tag'] = trim('
'; + + return [$start_div, $end_div]; + } + + /** + * Get the attributes from a plugin style div tag + * + * @param string $string + * + * @return object + */ + private static function getDivAttributes($string) + { + if (strpos($string, '="') !== false) + { + return self::getAttributesFromString($string); + } + + $parts = explode('|', $string); + $attributes = (object) []; + + foreach ($parts as $e) + { + if (strpos($e, ':') === false) + { + continue; + } + + list($key, $val) = explode(':', $e, 2); + $attributes->{$key} = $val; + } + + return $attributes; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/src/Protect.php b/deployed/regularlabs/libraries/regularlabs/src/Protect.php new file mode 100644 index 00000000..180ce304 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/src/Protect.php @@ -0,0 +1,1264 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Library; + +defined('_JEXEC') or die; + +use Joomla\CMS\Access\Access as JAccess; +use Joomla\CMS\Factory as JFactory; + +jimport('joomla.filesystem.file'); + +/** + * Class Protect + * @package RegularLabs\Library + */ +class Protect +{ + static $protect_start = ''; + static $protect_tags_start = ''; + static $html_safe_start = '___RL_PROTECTED___'; + static $html_safe_end = '___/RL_PROTECTED___'; + static $html_safe_tags_start = '___RL_PROTECTED_TAGS___'; + static $html_safe_tags_end = '___/RL_PROTECTED_TAGS___'; + static $sourcerer_tag = null; + static $sourcerer_characters = '{.}'; + + /** + * Check if page should be protected for given extension + * + * @param string $extension_alias + * + * @return bool + */ + public static function isDisabledByUrl($extension_alias = '') + { + // return if disabled via url + if (($extension_alias && JFactory::getApplication()->input->get('disable_' . $extension_alias))) + { + return true; + } + } + + /** + * Check if page should be protected for given extension + * + * @param bool $hastags + * @param array $restricted_formats + * + * @return bool + */ + public static function isRestrictedPage($hastags = false, $restricted_formats = []) + { + $cache_id = 'isRestrictedPage_' . $hastags . '_' . json_encode($restricted_formats); + + if (Cache::has($cache_id)) + { + return Cache::get($cache_id); + } + + $input = JFactory::getApplication()->input; + + // return if current page is in protected formats + // return if current page is an image + // return if current page is an installation page + // return if current page is Regular Labs QuickPage + // return if current page is a JoomFish or Josetta page + $is_restricted = ( + in_array($input->get('format'), $restricted_formats) + || in_array($input->get('view'), ['image', 'img']) + || in_array($input->get('type'), ['image', 'img']) + || in_array($input->get('task'), ['install.install', 'install.ajax_upload']) + || ($hastags + && ( + $input->getInt('rl_qp', 0) + || in_array($input->get('option'), ['com_joomfishplus', 'com_josetta']) + ) + ) + || (Document::isClient('administrator') + && in_array($input->get('option'), ['com_jdownloads']) + ) + ); + + return Cache::set( + $cache_id, + $is_restricted + ); + } + + /** + * @deprecated Use isDisabledByUrl() and isRestrictedPage() + */ + public static function isProtectedPage($extension_alias = '', $hastags = false, $exclude_formats = []) + { + if (self::isDisabledByUrl($extension_alias)) + { + return true; + } + + return self::isRestrictedPage($hastags, $exclude_formats); + } + + /** + * Check if the page is a restricted component + * + * @param array $restricted_components + * @param string $area + * + * @return bool + */ + public static function isRestrictedComponent($restricted_components, $area = 'component') + { + if ($area != 'component' && ! ($area == 'article' && JFactory::getApplication()->input->get('option') == 'com_content')) + { + return false; + } + + $restricted_components = + is_array($restricted_components) + ? $restricted_components + : explode(',', str_replace('|', ',', $restricted_components)); + + if (in_array(JFactory::getApplication()->input->get('option'), $restricted_components)) + { + return true; + } + + if (JFactory::getApplication()->input->get('option') == 'com_acymailing' + && ! in_array(JFactory::getApplication()->input->get('ctrl'), ['user', 'archive']) + ) + { + return true; + } + + return false; + } + + /** + * Check if the component is installed + * + * @param string $extension_alias + * + * @return bool + */ + public static function isComponentInstalled($extension_alias) + { + return file_exists(JPATH_ADMINISTRATOR . '/components/com_' . $extension_alias . '/' . $extension_alias . '.php'); + } + + /** + * Check if the component is installed + * + * @param string $extension_alias + * + * @return bool + */ + public static function isSystemPluginInstalled($extension_alias) + { + return file_exists(JPATH_PLUGINS . '/system/' . $extension_alias . '/' . $extension_alias . '.php'); + } + + /** + * Return the Regular Expressions string to match: + * The edit form + * + * @param int $regex_format + * + * @return string + */ + public static function getFormRegex() + { + return '(]*(' + . '(id|name)="(adminForm|postform|submissionForm|default_action_user|seblod_form|spEntryForm)"' + . '|action="[^"]*option=com_myjspace&(amp;)?view=see"' + . '))'; + } + + /** + * Protect all text based form fields + * + * @param string $string + * @param array $search_strings + */ + public static function protectFields(&$string, $search_strings = []) + { + // No specified strings tags found in the string + if ( ! self::containsStringsToProtect($string, $search_strings)) + { + return; + } + + $parts = StringHelper::split($string, ['', '']); + + foreach ($parts as &$part) + { + if ( ! self::containsStringsToProtect($part, $search_strings)) + { + continue; + } + + self::protectFieldsPart($part); + } + + $string = implode('', $parts); + } + + /** + * Check if the string contains certain substrings to protect + * + * @param string $string + * @param array $search_strings + * + * @return bool + */ + private static function containsStringsToProtect($string, $search_strings = []) + { + if ( + empty($string) + || ( + strpos($string, ']*)?)>(\s*)', + '<' . $temp_tag . '\1>\2', + $string + ); + + self::protectByRegex( + $string, + '(?:' + . '' + . '\s*)+' + ); + + // Replace back the temporarily replaced empty textareas + $string = str_replace($temp_tag, 'textarea', $string); + } + + /** + * Protect the input fields in the string + * + * @param string $string + */ + private static function protectFieldsInputFields(&$string) + { + if (strpos($string, '' + . '|' + . ')\s*)+' + ); + } + + /** + * Protect the script tags + * + * @param string $string + */ + public static function protectScripts(&$string) + { + if (strpos($string, '') === false) + { + return; + } + + self::protectByRegex( + $string, + '].*?' + ); + } + + /** + * Protect all html tags with some type of attributes/content + * + * @param string $string + */ + public static function protectHtmlTags(&$string) + { + // protect comment tags + self::protectHtmlCommentTags($string); + + // protect html tags + self::protectByRegex($string, '<[a-z][^>]*(?:="[^"]*"|=\'[^\']*\')+[^>]*>'); + } + + /** + * Protect all html comment tags + * + * @param string $string + */ + public static function protectHtmlCommentTags(&$string) + { + // protect comment tags + self::protectByRegex($string, '<\!--.*?-->'); + } + + /** + * Protect text by given regex + * + * @param string $string + * @param string $regex + */ + public static function protectByRegex(&$string, $regex) + { + RegEx::matchAll($regex, $string, $matches, null, PREG_PATTERN_ORDER); + + if (empty($matches)) + { + return; + } + + $matches = array_unique($matches[0]); + $replacements = []; + + foreach ($matches as $match) + { + $replacements[] = self::protectString($match); + } + + $string = str_replace($matches, $replacements, $string); + } + + /** + * Protect given plugin style tags + * + * @param string $string + * @param array $tags + * @param bool $include_closing_tags + */ + public static function protectTags(&$string, $tags = [], $include_closing_tags = true) + { + list($tags, $protected) = self::prepareTags($tags, $include_closing_tags); + + $string = str_replace($tags, $protected, $string); + } + + /** + * Replace any protected tags to original + * + * @param string $string + * @param array $tags + * @param bool $include_closing_tags + */ + public static function unprotectTags(&$string, $tags = [], $include_closing_tags = true) + { + list($tags, $protected) = self::prepareTags($tags, $include_closing_tags); + + $string = str_replace($protected, $tags, $string); + } + + /** + * Protect array of strings + * + * @param string $string + * @param array $unprotected + * @param array $protected + */ + public static function protectInString(&$string, $unprotected = [], $protected = []) + { + $protected = empty($protected) ? self::protectArray($unprotected) : $protected; + + $string = str_replace($unprotected, $protected, $string); + } + + /** + * Replace any protected tags to original + * + * @param string $string + * @param array $unprotected + * @param array $protected + */ + public static function unprotectInString(&$string, $unprotected = [], $protected = []) + { + $protected = empty($protected) ? self::protectArray($unprotected) : $protected; + + $string = str_replace($protected, $unprotected, $string); + } + + /** + * Return the sourcerer tag name and characters + * + * @return array + */ + public static function getSourcererTag() + { + if ( ! is_null(self::$sourcerer_tag)) + { + return [self::$sourcerer_tag, self::$sourcerer_characters]; + } + + $parameters = Parameters::getInstance()->getPluginParams('sourcerer'); + + self::$sourcerer_tag = isset($parameters->syntax_word) ? $parameters->syntax_word : ''; + self::$sourcerer_characters = isset($parameters->tag_characters) ? $parameters->tag_characters : '{.}'; + + return [self::$sourcerer_tag, self::$sourcerer_characters]; + } + + /** + * Protect all Sourcerer blocks + * + * @param string $string + */ + public static function protectSourcerer(&$string) + { + list($tag, $characters) = self::getSourcererTag(); + + if (empty($tag)) + { + return; + } + + list($start, $end) = explode('.', $characters); + + if (strpos($string, $start . '/' . $tag . $end) === false) + { + return; + } + + $regex = RegEx::quote($start . $tag) + . '[\s\}].*?' + . RegEx::quote($start . '/' . $tag . $end); + + RegEx::matchAll($regex, $string, $matches, null, PREG_PATTERN_ORDER); + + if (empty($matches)) + { + return; + } + + $matches = array_unique($matches[0]); + + foreach ($matches as $match) + { + $string = str_replace($match, self::protectString($match), $string); + } + } + + /** + * Protect complete AdminForm + * + * @param string $string + * @param array $tags + * @param bool $include_closing_tags + */ + public static function protectForm(&$string, $tags = [], $include_closing_tags = true) + { + if ( ! Document::isEditPage()) + { + return; + } + + list($tags, $protected_tags) = self::prepareTags($tags, $include_closing_tags); + + $string = RegEx::replace(self::getFormRegex(), '\1', $string); + $string = explode('', $string); + + foreach ($string as $i => &$string_part) + { + if (empty($string_part) || ! fmod($i, 2)) + { + continue; + } + + self::protectFormPart($string_part, $tags, $protected_tags); + } + + $string = implode('', $string); + } + + /** + * Protect part of the AdminForm + * + * @param string $string + * @param array $tags + * @param array $protected_tags + */ + private static function protectFormPart(&$string, $tags = [], $protected_tags = []) + { + if (strpos($string, '') === false) + { + return; + } + + // Protect entire form + if (empty($tags)) + { + $form_parts = explode('', $string, 2); + $form_parts[0] = self::protectString($form_parts[0] . ''); + $string = implode('', $form_parts); + + return; + } + + $regex_tags = RegEx::quote($tags); + + if ( ! RegEx::match($regex_tags, $string)) + { + return; + } + + $form_parts = explode('', $string, 2); + // protect tags only inside form fields + RegEx::matchAll( + '(?:]*>.*?<\/textarea>|]*>)', + $form_parts[0], + $matches, + null, + PREG_PATTERN_ORDER + ); + + if (empty($matches)) + { + return; + } + + $matches = array_unique($matches[0]); + + foreach ($matches as $match) + { + $field = str_replace($tags, $protected_tags, $match); + $form_parts[0] = str_replace($match, $field, $form_parts[0]); + } + + $string = implode('', $form_parts); + } + + /** + * Replace any protected text to original + * + * @param string|array $string + */ + public static function unprotect(&$string) + { + if (is_array($string)) + { + foreach ($string as &$part) + { + self::unprotect($part); + } + + return; + } + + self::unprotectByDelimiters( + $string, + [self::$protect_tags_start, self::$protect_tags_end] + ); + + self::unprotectByDelimiters( + $string, + [self::$protect_start, self::$protect_end] + ); + + if (StringHelper::contains($string, [self::$protect_tags_start, self::$protect_tags_end, self::$protect_start, self::$protect_end])) + { + self::unprotect($string); + } + } + + /** + * @param string $string + * @param array $delimiters + */ + private static function unprotectByDelimiters(&$string, $delimiters) + { + if ( ! StringHelper::contains($string, $delimiters)) + { + return; + } + + $regex = RegEx::preparePattern(RegEx::quote($delimiters), 's', $string); + + $parts = preg_split($regex, $string); + + foreach ($parts as $i => &$part) + { + if ($i % 2 == 0) + { + continue; + } + + $part = base64_decode($part); + } + + $string = implode('', $parts); + } + + /** + * Replace any protected text to original + * + * @param string $string + */ + public static function convertProtectionToHtmlSafe(&$string) + { + $string = str_replace( + [ + self::$protect_start, + self::$protect_end, + self::$protect_tags_start, + self::$protect_tags_end, + ], + [ + self::$html_safe_start, + self::$html_safe_end, + self::$html_safe_tags_start, + self::$html_safe_tags_end, + ], + $string + ); + } + + /** + * Replace any protected text to original + * + * @param string $string + */ + public static function unprotectHtmlSafe(&$string) + { + $string = str_replace( + [ + self::$html_safe_start, + self::$html_safe_end, + self::$html_safe_tags_start, + self::$html_safe_tags_end, + ], + [ + self::$protect_start, + self::$protect_end, + self::$protect_tags_start, + self::$protect_tags_end, + ], + $string + ); + + self::unprotect($string); + } + + /** + * Prepare the tags and protected tags array + * + * @param array $tags + * @param bool $include_closing_tags + * + * @return bool|mixed + */ + private static function prepareTags($tags, $include_closing_tags = true) + { + if ( ! is_array($tags)) + { + $tags = [$tags]; + } + + $cache_id = 'prepareTags_' . json_encode($tags) . '_' . $include_closing_tags; + + if (Cache::has($cache_id)) + { + return Cache::get($cache_id); + } + + foreach ($tags as $i => $tag) + { + if (StringHelper::is_alphanumeric($tag[0])) + { + $tag = '{' . $tag; + } + + $tags[$i] = $tag; + + if ($include_closing_tags) + { + $tags[] = RegEx::replace('^([^a-z0-9]+)', '\1/', $tag); + } + } + + return Cache::set( + $cache_id, + [$tags, self::protectArray($tags, 1)] + ); + } + + /** + * Encode string + * + * @param string $string + * @param int $is_tag + * + * @return string + */ + public static function protectString($string, $is_tag = false) + { + if ($is_tag) + { + return self::$protect_tags_start . base64_encode($string) . self::$protect_tags_end; + } + + return self::$protect_start . base64_encode($string) . self::$protect_end; + } + + /** + * Decode string + * + * @param string $string + * @param int $is_tag + * + * @return string + */ + public static function unprotectString($string, $is_tag = false) + { + if ($is_tag) + { + return self::$protect_tags_start . base64_decode($string) . self::$protect_tags_end; + } + + return self::$protect_start . base64_decode($string) . self::$protect_end; + } + + /** + * Encode tag string + * + * @param string $string + * + * @return string + */ + public static function protectTag($string) + { + return self::protectString($string, 1); + } + + /** + * Encode array of strings + * + * @param array $array + * @param int $is_tag + * + * @return mixed + */ + public static function protectArray($array, $is_tag = false) + { + foreach ($array as &$string) + { + $string = self::protectString($string, $is_tag); + } + + return $array; + } + + /** + * Decode array of strings + * + * @param array $array + * @param int $is_tag + * + * @return mixed + */ + public static function unprotectArray($array, $is_tag = false) + { + foreach ($array as &$string) + { + $string = self::unprotectString($string, $is_tag); + } + + return $array; + } + + /** + * Replace any protected tags to original + * + * @param string $string + * @param array $tags + */ + public static function unprotectForm(&$string, $tags = []) + { + // Protect entire form + if (empty($tags)) + { + self::unprotect($string); + + return; + } + + self::unprotectTags($string, $tags); + } + + /** + * Wrap string in comment tags + * + * @param string $name + * @param string $comment + * + * @return string + */ + public static function wrapInCommentTags($name, $string) + { + list($start, $end) = self::getCommentTags($name); + + return $start . $string . $end; + } + + /** + * Get the html comment tags + * + * @param string $name + * + * @return array + */ + public static function getCommentTags($name = '') + { + return [self::getCommentStartTag($name), self::getCommentEndTag($name)]; + } + + /** + * Get the html start comment tags + * + * @param string $name + * + * @return string + */ + public static function getCommentStartTag($name = '') + { + return ''; + } + + /** + * Get the html end comment tags + * + * @param string $name + * + * @return string + */ + public static function getCommentEndTag($name = '') + { + return ''; + } + + /** + * Create a html comment from given comment string + * + * @param string $name + * @param string $comment + * + * @return string + */ + public static function getMessageCommentTag($name, $comment) + { + list($start, $end) = self::getMessageCommentTags($name); + + return $start . $comment . $end; + } + + /** + * Get the start and end parts for the html message comment tag + * + * @param string $name + * + * @return array + */ + public static function getMessageCommentTags($name = '') + { + return ['']; + } + + /** + * Get the start and end parts for the inline comment tags for scripts/styles + * + * @param string $name + * @param string $type + * + * @return array + */ + public static function getInlineCommentTags($name = '', $type = '', $regex = false) + { + if ($regex) + { + $type = 'TYPE_PLACEHOLDER'; + } + + $start = '/* START: ' . $name . ' ' . $type . ' */'; + $end = '/* END: ' . $name . ' ' . $type . ' */'; + + if ($regex) + { + $start = str_replace($type, '[a-z]*', RegEx::quote($start)); + $end = str_replace($type, '[a-z]*', RegEx::quote($end)); + } + + return [$start, $end]; + } + + /** + * Wraps a style or javascript declaration with comment tags + * + * @param string $content + * @param string $name + * @param string $type + * @param bool $minify + */ + public static function wrapDeclaration($content = '', $name = '', $type = 'styles', $minify = true) + { + if (empty($name)) + { + return $content; + } + + list($start, $end) = self::getInlineCommentTags($name, $type); + + $spacer = $minify ? ' ' : "\n"; + + return $start . $spacer . $content . $spacer . $end; + } + + /** + * Wraps a javascript declaration with comment tags + * + * @param string $content + * @param string $name + * @param bool $minify + */ + public static function wrapScriptDeclaration($content = '', $name = '', $minify = true) + { + return self::wrapDeclaration($content, $name, 'scripts', $minify); + } + + /** + * Wraps a stylesheet declaration with comment tags + * + * @param string $content + * @param string $name + * @param bool $minify + */ + public static function wrapStyleDeclaration($content = '', $name = '', $minify = true) + { + return self::wrapDeclaration($content, $name, 'styles', $minify); + } + + /** + * Remove area comments in html + * + * @param string $string + * @param string $prefix + */ + public static function removeAreaTags(&$string, $prefix = '') + { + $string = RegEx::replace('', '', $string, 's'); + } + + /** + * Remove comments in html + * + * @param string $string + * @param string $name + */ + public static function removeCommentTags(&$string, $name = '') + { + list($start, $end) = self::getCommentTags($name); + + $string = str_replace( + [ + $start, $end, + htmlentities($start), htmlentities($end), + urlencode($start), urlencode($end), + ], '', $string + ); + + list($start, $end) = self::getMessageCommentTags($name); + + $string = RegEx::replace( + RegEx::quote($start) . '.*?' . RegEx::quote($end), + '', + $string + ); + } + + /** + * Remove inline comments in scrips and styles + * + * @param string $string + * @param string $name + */ + public static function removeInlineComments(&$string, $name) + { + list($start, $end) = Protect::getInlineCommentTags($name, null, true); + $string = RegEx::replace('(' . $start . '|' . $end . ')', "\n", $string); + } + + /** + * Remove left over plugin tags + * + * @param string $string + * @param array $tags + * @param string $character_start + * @param string $character_end + * @param bool $keep_content + */ + public static function removePluginTags(&$string, $tags, $character_start = '{', $character_end = '{', $keep_content = true) + { + $character_start = RegEx::quote($character_start); + $character_end = RegEx::quote($character_end); + + foreach ($tags as $tag) + { + if ( ! is_array($tag)) + { + $tag = [$tag, $tag]; + } + + if (count($tag) < 2) + { + $tag = [$tag[0], $tag[0]]; + } + + $regex = $character_start . RegEx::quote($tag[0]) . '(?:\s.*?)?' . $character_end + . '(.*?)' + . $character_start . '/' . RegEx::quote($tag[1]) . $character_end; + + $replace = $keep_content ? '\1' : ''; + + $string = RegEx::replace($regex, $replace, $string); + } + } + + /** + * Remove tags from title tags + * + * @param string $string + * @param array $tags + * @param bool $include_closing_tags + * @param array $html_tags + */ + public static function removeFromHtmlTagContent(&$string, $tags, $include_closing_tags = true, $html_tags = ['title']) + { + list($tags, $protected) = self::prepareTags($tags, $include_closing_tags); + + if ( ! is_array($html_tags)) + { + $html_tags = [$html_tags]; + } + + RegEx::matchAll('(<(' . implode('|', $html_tags) . ')(?:\s[^>]*?)>)(.*?)()', $string, $matches); + + if (empty($matches)) + { + return; + } + + foreach ($matches as $match) + { + $content = $match[3]; + foreach ($tags as $tag) + { + $content = RegEx::replace(RegEx::quote($tag) . '.*?\}', '', $content); + } + $string = str_replace($match[0], $match[1] . $content . $match[4], $string); + } + } + + /** + * Remove tags from tag attributes + * + * @param string $string + * @param array $tags + * @param string $attributes + * @param bool $include_closing_tags + */ + public static function removeFromHtmlTagAttributes(&$string, $tags, $attributes = 'ALL', $include_closing_tags = true) + { + list($tags, $protected) = self::prepareTags($tags, $include_closing_tags); + + if ($attributes == 'ALL') + { + $attributes = ['[a-z][a-z0-9-_]*']; + } + + if ( ! is_array($attributes)) + { + $attributes = [$attributes]; + } + + RegEx::matchAll( + '\s(?:' . implode('|', $attributes) . ')\s*=\s*".*?"', + $string, + $matches, + null, + PREG_PATTERN_ORDER + ); + + if (empty($matches) || empty($matches[0])) + { + return; + } + + $matches = array_unique($matches[0]); + + // preg_quote all tags + $tags_regex = RegEx::quote($tags) . '.*?\}'; + + foreach ($matches as $match) + { + if ( ! StringHelper::contains($match, $tags)) + { + continue; + } + + $title = $match; + + $title = RegEx::replace($tags_regex, '', $title); + + $string = StringHelper::replaceOnce($match, $title, $string); + } + } + + /** + * Check if article passes security levels + * + * @param object $article + * @param array $securtiy_levels + * + * @return bool|int + */ + public static function articlePassesSecurity(&$article, $securtiy_levels = []) + { + if ( ! isset($article->created_by)) + { + return true; + } + + if (empty($securtiy_levels)) + { + return true; + } + + if (is_string($securtiy_levels)) + { + $securtiy_levels = [$securtiy_levels]; + } + + if ( + ! is_array($securtiy_levels) + || in_array('-1', $securtiy_levels) + ) + { + return true; + } + + // Lookup group level of creator + $user_groups = new JAccess; + $user_groups = $user_groups->getGroupsByUser($article->created_by); + + // Return true if any of the security levels are found in the users groups + return count(array_intersect($user_groups, $securtiy_levels)); + } + + /** + * Replace in protect array + * + * @param array $array + * @param string $search + * @param string $replacement + */ + public static function replaceInArray(&$array, $search, $replacement) + { + foreach ($array as $key => &$string) + { + // only do something if string is not empty + // or on uneven count = not yet protected + if (trim($string) == '' || fmod($key, 2)) + { + continue; + } + + $array[$key] = str_replace($search, $replacement, $string); + } + } + + /** + * Replace in protect array using Regular Expressions + * + * @param array $array + * @param string $search + * @param string $replacement + */ + public static function pregReplaceInArray(&$array, $search, $replacement) + { + foreach ($array as $key => &$string) + { + // only do something if string is not empty + // or on uneven count = not yet protected + if (trim($string) == '' || fmod($key, 2)) + { + continue; + } + + $array[$key] = RegEx::replace($search, $replacement, $string); + } + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/src/RegEx.php b/deployed/regularlabs/libraries/regularlabs/src/RegEx.php new file mode 100644 index 00000000..4c2ab0e2 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/src/RegEx.php @@ -0,0 +1,242 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Library; + +defined('_JEXEC') or die; + +/** + * Class RegEx + * @package RegularLabs\Library + */ +class RegEx +{ + /** + * Perform a regular expression search and replace + * + * @param string $pattern + * @param string $replacement + * @param string $string + * @param string $options + * @param int $limit + * @param int $count + * + * @return string + */ + public static function replace($pattern, $replacement, $string, $options = null, $limit = -1, &$count = null) + { + if ( ! is_string($pattern) || $pattern == '' || ! is_string($string) || $string == '') + { + return $string; + } + + $pattern = self::preparePattern($pattern, $options, $string); + + return preg_replace($pattern, $replacement, $string, $limit, $count); + } + + /** + * Perform a regular expression search and replace once + * + * @param string $pattern + * @param string $replacement + * @param string $string + * @param string $options + * + * @return string + */ + public static function replaceOnce($pattern, $replacement, $string, $options = null) + { + return self::replace($pattern, $replacement, $string, $options, 1); + } + + /** + * Perform a regular expression match + * + * @param string $pattern + * @param string $string + * @param null $matches + * @param string $options + * @param int $flags + * + * @return int + */ + public static function match($pattern, $string, &$matches = null, $options = null, $flags = 0) + { + if ( ! is_string($pattern) || $pattern == '' || ! is_string($string) || $string == '') + { + return false; + } + + $pattern = self::preparePattern($pattern, $options, $string); + + return preg_match($pattern, $string, $matches, $flags); + } + + /** + * Perform a global regular expression match + * + * @param string $pattern + * @param string $string + * @param null $matches + * @param string $options + * @param int $flags + * + * @return int + */ + public static function matchAll($pattern, $string, &$matches = null, $options = null, $flags = PREG_SET_ORDER) + { + if ( ! is_string($pattern) || $pattern == '' || ! is_string($string) || $string == '') + { + $matches = []; + + return false; + } + + $pattern = self::preparePattern($pattern, $options, $string); + + return preg_match_all($pattern, $string, $matches, $flags); + } + + /** + * preg_quote the given string or array of strings + * + * @param string|array $data + * @param string $name + * @param string $delimiter + * + * @return string + */ + public static function quote($data, $name = '', $delimiter = '#', $capture = true) + { + if (is_array($data)) + { + $array = self::quoteArray($data, $delimiter); + + $prefix = '?!'; + if ($capture) + { + $prefix = $name ? '?<' . $name . '>' : ''; + } + + return '(' . $prefix . implode('|', $array) . ')'; + } + + return preg_quote($data, $delimiter); + } + + /** + * reverse preg_quote the given string + * + * @param string $string + * @param string $delimiter + * + * @return string + */ + public static function unquote($string, $delimiter = '#') + { + return strtr($string, [ + '\\' . $delimiter => $delimiter, + '\\.' => '.', + '\\\\' => '\\', + '\\+' => '+', + '\\*' => '*', + '\\?' => '?', + '\\[' => '[', + '\\^' => '^', + '\\]' => ']', + '\\$' => '$', + '\\(' => '(', + '\\)' => ')', + '\\{' => '{', + '\\}' => '}', + '\\=' => '=', + '\\!' => '!', + '\\<' => '<', + '\\>' => '>', + '\\|' => '|', + '\\:' => ':', + '\\-' => '-', + ]); + } + + /** + * preg_quote the given array of strings + * + * @param array $array + * @param string $delimiter + * + * @return array + */ + public static function quoteArray($array = [], $delimiter = '#') + { + array_walk($array, function (&$part, $key, $delimiter) { + $part = self::quote($part, $delimiter); + }, $delimiter); + + return $array; + } + + /** + * Make a string a valid regular expression pattern + * + * @param string $pattern + * @param string $options + * @param string $string + * + * @return string + */ + public static function preparePattern($pattern, $options = null, $string = '') + { + if (is_array($pattern)) + { + return self::preparePatternArray($pattern, $options, $string); + } + + if (substr($pattern, 0, 1) != '#') + { + $pattern = '#' . $pattern . '#'; + } + + $options = ! is_null($options) ? $options : 'si'; + + if (substr($pattern, -1, 1) == '#') + { + $pattern .= $options; + } + + if (StringHelper::detectUTF8($string)) + { + // use utf-8 + return $pattern . 'u'; + } + + return $pattern; + } + + /** + * Make an array of strings valid regular expression patterns + * + * @param array $pattern + * @param string $options + * @param string $string + * + * @return array + */ + private static function preparePatternArray($pattern, $options = null, $string = '') + { + array_walk($pattern, function (&$subpattern, $key, $string) { + $subpattern = self::preparePattern($subpattern, $options = null, $string); + }, $string); + + return $pattern; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/src/ShowOn.php b/deployed/regularlabs/libraries/regularlabs/src/ShowOn.php new file mode 100644 index 00000000..d3d73245 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/src/ShowOn.php @@ -0,0 +1,57 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Library; + +use Joomla\CMS\Form\FormHelper as JFormHelper; +use RegularLabs\Library\Document as RL_Document; + +defined('_JEXEC') or die; + +/** + * Class ShowOn + * @package RegularLabs\Library + */ +class ShowOn +{ + public static function open($condition = '', $formControl = '', $group = '', $class = '') + { + if ( ! $condition) + { + return self::close(); + } + + RL_Document::loadFormDependencies(); + + $json = json_encode(JFormHelper::parseShowOnConditions($condition, $formControl, $group)); + + $class = $class ? ' class="' . $class . '"' : ''; + + return '
'; + } + + public static function close() + { + return '
'; + } + + public static function show($string = '', $condition = '', $formControl = '', $group = '', $animate = true, $class = '') + { + if ( ! $condition || ! $string) + { + return $string; + } + + return self::open($condition, $formControl, $group, $animate, $class) + . $string + . self::close(); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/src/StringHelper.php b/deployed/regularlabs/libraries/regularlabs/src/StringHelper.php new file mode 100644 index 00000000..65dd5016 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/src/StringHelper.php @@ -0,0 +1,284 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Library; + +defined('_JEXEC') or die; + +use Joomla\String\Normalise; + +/** + * Class StringHelper + * @package RegularLabs\Library + */ +class StringHelper + extends \Joomla\String\StringHelper +{ + /** + * Decode html entities in string or array of strings + * + * @param string $data + * @param int $quote_style + * @param string $encoding + * + * @return array|string + */ + public static function html_entity_decoder($data, $quote_style = ENT_QUOTES, $encoding = 'UTF-8') + { + if (is_array($data)) + { + array_walk($data, function (&$part, $key, $quote_style, $encoding) { + $part = self::html_entity_decoder($part, $quote_style, $encoding); + }, $quote_style, $encoding); + + return $data; + } + + if ( ! is_string($data)) + { + return $data; + } + + return html_entity_decode($data, $quote_style | ENT_HTML5, $encoding); + } + + /** + * Replace the given replace string once in the main string + * + * @param string $search + * @param string $replace + * @param string $string + * + * @return string + */ + public static function replaceOnce($search, $replace, $string) + { + if (empty($search) || empty($string)) + { + return $string; + } + + $pos = strpos($string, $search); + + if ($pos === false) + { + return $string; + } + + return substr_replace($string, $replace, $pos, strlen($search)); + } + + /** + * Check if any of the needles are found in any of the haystacks + * + * @param $haystacks + * @param $needles + * + * @return bool + */ + public static function contains($haystacks, $needles) + { + $haystacks = (array) $haystacks; + $needles = (array) $needles; + + foreach ($haystacks as $haystack) + { + foreach ($needles as $needle) + { + if (strpos($haystack, $needle) !== false) + { + return true; + } + } + } + + return false; + } + + /** + * Check if string is alphanumerical + * + * @param string $string + * + * @return bool + */ + public static function is_alphanumeric($string) + { + if (function_exists('ctype_alnum')) + { + return (bool) ctype_alnum($string); + } + + return (bool) RegEx::match('^[a-z0-9]+$', $string); + } + + /** + * Check if string is a valid key / alias (alphanumeric with optional _ or - chars) + * + * @param string $string + * + * @return bool + */ + public static function is_key($string) + { + return RegEx::match('^[a-z][a-z0-9-_]*$', trim($string)); + } + + /** + * Split a long string into parts (array) + * + * @param string $string + * @param array $delimiters Array of strings to split the string on + * @param int $max_length Maximum length of each part + * @param bool $maximize_parts If true, the different parts will be made as large as possible (combining consecutive short string elements) + * + * @return array + */ + public static function split($string, $delimiters = [], $max_length = 10000, $maximize_parts = true) + { + // String is too short to split + if (strlen($string) < $max_length) + { + return [$string]; + } + + // No delimiters given or found + if (empty($delimiters) || ! self::contains($string, $delimiters)) + { + return [$string]; + } + + // preg_quote all delimiters + $array = preg_split('#' . RegEx::quote($delimiters) . '#s', $string, null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); + + if ( ! $maximize_parts) + { + return $array; + } + + $new_array = []; + foreach ($array as $part) + { + // First element, add to new array + if ( ! count($new_array)) + { + $new_array[] = $part; + continue; + } + + $last_part = end($new_array); + $last_key = key($new_array); + + // If last and current parts are longer than max_length, then simply add as new value + if (strlen($last_part) + strlen($part) > $max_length) + { + $new_array[] = $part; + continue; + } + + // Concatenate part to previous part + $new_array[$last_key] .= $part; + } + + return $new_array; + } + + /** + * Check whether string is a UTF-8 encoded string + * + * @param string $string + * + * @return bool + */ + public static function detectUTF8($string = '') + { + // Try to check the string via the mb_check_encoding function + if (function_exists('mb_check_encoding')) + { + return mb_check_encoding($string, 'UTF-8'); + } + + // Otherwise: Try to check the string via the iconv function + if (function_exists('iconv')) + { + $converted = iconv('UTF-8', 'UTF-8//IGNORE', $string); + + return (md5($converted) == md5($string)); + } + + // As last fallback, check if the preg_match finds anything using the unicode flag + return preg_match('#.#u', $string); + } + + /** + * Converts a string to a UTF-8 encoded string + * + * @param string $string + * + * @return string + */ + public static function convertToUtf8(&$string = '') + { + if (self::detectUTF8($string)) + { + // Already UTF-8, so skip + return $string; + } + + if ( ! function_exists('iconv')) + { + // Still need to find a stable fallback + return $string; + } + + $utf8_string = @iconv('UTF8', 'UTF-8//IGNORE', $string); + + if (empty($utf8_string)) + { + return $string; + } + + return $utf8_string; + } + + /** + * Converts a camelcased string to a underscore separated string + * eg: FooBar => foo_bar + * + * @param string $string + * @param bool $tolowercase + * + * @return string + */ + public static function camelToUnderscore($string = '', $tolowercase = true) + { + $string = Normalise::toUnderscoreSeparated(Normalise::fromCamelCase($string)); + + if ( ! $tolowercase) + { + return $string; + } + + return strtolower($string); + } + + /** + * Removes html tags from string + * + * @param string $string + * + * @return string + */ + public static function removeHtml($string) + { + return Html::removeHtmlTags($string); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/src/Title.php b/deployed/regularlabs/libraries/regularlabs/src/Title.php new file mode 100644 index 00000000..904c4f75 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/src/Title.php @@ -0,0 +1,111 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Library; + +defined('_JEXEC') or die; + +/** + * Class Title + * @package RegularLabs\Library + */ +class Title +{ + /** + * Cleans the string to make it usable as a title + * + * @param string $string + * @param bool $strip_tags + * @param bool $strip_spaces + * + * @return string + */ + public static function clean($string = '', $strip_tags = false, $strip_spaces = true) + { + if (empty($string)) + { + return ''; + } + + // remove comment tags + $string = RegEx::replace('<\!--.*?-->', '', $string); + + // replace weird whitespace + $string = str_replace(chr(194) . chr(160), ' ', $string); + + if ($strip_tags) + { + // remove svgs + $string = RegEx::replace('', '', $string); + // remove html tags + $string = RegEx::replace(']*>', '', $string); + // remove comments tags + $string = RegEx::replace('<\!--.*?-->', '', $string); + } + + if ($strip_spaces) + { + // Replace html spaces + $string = str_replace([' ', ' '], ' ', $string); + + // Remove duplicate whitespace + $string = RegEx::replace('[ \n\r\t]+', ' ', $string); + } + + return trim($string); + } + + /** + * Creates an array of different syntaxes of titles to match against a url variable + * + * @param array $titles + * + * @return array + */ + public static function getUrlMatches($titles = []) + { + $matches = []; + foreach ($titles as $title) + { + $matches[] = $title; + $matches[] = StringHelper::strtolower($title); + } + + $matches = array_unique($matches); + + foreach ($matches as $title) + { + $matches[] = htmlspecialchars(StringHelper::html_entity_decoder($title)); + } + + $matches = array_unique($matches); + + foreach ($matches as $title) + { + $matches[] = urlencode($title); + $matches[] = utf8_decode($title); + $matches[] = str_replace(' ', '', $title); + $matches[] = trim(RegEx::replace('[^a-z0-9]', '', $title)); + $matches[] = trim(RegEx::replace('[^a-z]', '', $title)); + } + + $matches = array_unique($matches); + + foreach ($matches as $i => $title) + { + $matches[$i] = trim(str_replace('?', '', $title)); + } + + $matches = array_diff(array_unique($matches), ['', '-']); + + return $matches; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/src/Uri.php b/deployed/regularlabs/libraries/regularlabs/src/Uri.php new file mode 100644 index 00000000..9e2801c9 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/src/Uri.php @@ -0,0 +1,125 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Library; + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; +use Joomla\CMS\Router\Route as JRoute; +use Joomla\CMS\Uri\Uri as JUri; + +/** + * Class Uri + * @package RegularLabs\Library + */ +class Uri +{ + /** + * Returns the full uri and optionally adds/replaces the hash + * + * @param string $hash + * + * @return string + */ + public static function get($hash = '') + { + $url = JUri::getInstance()->toString(); + + if ($hash == '') + { + return $url; + } + + return self::appendHash($url, $hash); + } + + /** + * Appends the given hash to the url or replaces it if there is already one + * + * @param string $url + * @param string $hash + * + * @return string + */ + private static function appendHash($url = '', $hash = '') + { + if (empty($hash)) + { + return $url; + } + + if (strpos($url, '#') !== false) + { + $url = substr($url, 0, strpos($url, '#')); + } + + return $url . '#' . $hash; + } + + public static function isExternal($url) + { + if (strpos($url, '://') === false) + { + return false; + } + + // hostname: give preference to SERVER_NAME, because this includes subdomains + $hostname = ($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST']; + + return ! (strpos(RegEx::replace('^.*?://', '', $url), $hostname) === 0); + } + + public static function route($url) + { + return JRoute::_(JUri::root(true) . '/' . $url); + } + + public static function encode($string) + { + return urlencode(base64_encode(gzdeflate($string))); + } + + public static function decode($string) + { + return gzinflate(base64_decode(urldecode($string))); + } + + public static function createCompressedAttributes($string) + { + $parameters = []; + + $compressed = base64_encode(gzdeflate($string)); + $chunk_length = ceil(strlen($compressed) / 10); + $chunks = str_split($compressed, $chunk_length); + + foreach ($chunks as $i => $chunk) + { + $parameters[] = 'rlatt_' . $i . '=' . urlencode($chunk); + } + + return implode('&', $parameters); + } + + public static function getCompressedAttributes() + { + $input = JFactory::getApplication()->input; + + $compressed = ''; + + for ($i = 0; $i < 10; $i++) + { + $compressed .= $input->getString('rlatt_' . $i, ''); + } + + return gzinflate(base64_decode($compressed)); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/src/Version.php b/deployed/regularlabs/libraries/regularlabs/src/Version.php new file mode 100644 index 00000000..d96d99fc --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/src/Version.php @@ -0,0 +1,334 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Library; + +defined('_JEXEC') or die; + +use Joomla\CMS\Component\ComponentHelper as JComponentHelper; +use Joomla\CMS\Factory as JFactory; +use Joomla\CMS\HTML\HTMLHelper as JHtml; +use Joomla\CMS\Language\Text as JText; +use Joomla\CMS\Router\Route as JRoute; +use Joomla\CMS\Session\Session as JSession; +use Joomla\CMS\Uri\Uri as JUri; + +jimport('joomla.filesystem.file'); + +/** + * Class Version + * @package RegularLabs\Library + */ +class Version +{ + /** + * Get the version of the given extension + * + * @param $alias + * @param string $type + * @param string $folder + * + * @return string + */ + public static function get($alias, $type = 'component', $folder = 'system') + { + return trim(Extension::getXmlValue('version', $alias, $type, $folder)); + } + + /** + * Get the version of the given plugin + * + * @param $alias + * @param string $folder + * + * @return string + */ + public static function getPluginVersion($alias, $folder = 'system') + { + return self::get($alias, 'plugin', $folder); + } + + /** + * Get the version of the given component + * + * @param $alias + * + * @return string + */ + public static function getComponentVersion($alias) + { + return self::get($alias, 'component'); + } + + /** + * Get the version of the given module + * + * @param $alias + * + * @return string + */ + public static function getModuleVersion($alias) + { + return self::get($alias, 'module'); + } + + /** + * Get the version message + * + * @param $alias + * + * @return string + */ + public static function getMessage($alias) + { + if ( ! $alias) + { + return ''; + } + + $name = Extension::getNameByAlias($alias); + $alias = Extension::getAliasByName($alias); + + if ( ! $version = self::get($alias)) + { + return ''; + } + + Document::loadMainDependencies(); + + $url = 'download.regularlabs.com/extensions.xml?j=3&e=' . $alias; + $script = " + jQuery(document).ready(function() { + RegularLabsScripts.loadajax( + '" . $url . "', + 'RegularLabsScripts.displayVersion( data, \"" . $alias . "\", \"" . str_replace(['FREE', 'PRO'], '', $version) . "\" )', + 'RegularLabsScripts.displayVersion( \"\" )', + null, null, null, (60 * 60) + ); + }); + "; + JFactory::getDocument()->addScriptDeclaration($script); + + return ''; + } + + /** + * Get the full footer + * + * @param $name + * @param int $copyright + * + * @return string + */ + public static function getFooter($name, $copyright = true) + { + Document::loadMainDependencies(); + + $html = []; + + $html[] = ''; + + if ($copyright) + { + $html[] = ''; + $html[] = ''; + $html[] = ''; + } + + return ''; + } + + /** + * Get the version message text + * + * @param $alias + * @param $name + * @param $version + * + * @return array|string + */ + private static function getMessageText($alias, $name, $version) + { + list($url, $onclick) = self::getUpdateLink($alias, $version); + + $href = $onclick ? '' : 'href="' . $url . '" target="_blank" '; + $onclick = $onclick ? 'onclick="' . $onclick . '" ' : ''; + + $is_pro = strpos($version, 'PRO') !== false; + $version = str_replace(['FREE', 'PRO'], ['', ' [PRO]'], $version); + + $msg = '
' + . '' + . JText::sprintf('RL_NEW_VERSION_OF_AVAILABLE', JText::_($name)) + . '' + . '
' + . '' + . ' ' + . StringHelper::html_entity_decoder(JText::sprintf('RL_UPDATE_TO', '')) + . ''; + + if ( ! $is_pro) + { + $msg .= ' ' + . ' ' + . JText::_('RL_GO_PRO') + . ''; + } + + $msg .= '
' + . '' + . '[ ' + . JText::_('RL_CHANGELOG') + . ' ]' + . '
' + . JText::sprintf('RL_CURRENT_VERSION', $version) + . '
' + . '
'; + + return StringHelper::html_entity_decoder($msg); + } + + /** + * Get the url and onclick function for the update link + * + * @param $alias + * @param $version + * + * @return array + */ + private static function getUpdateLink($alias, $version) + { + $is_pro = strpos($version, 'PRO') !== false; + + if ( + ! file_exists(JPATH_ADMINISTRATOR . '/components/com_regularlabsmanager/regularlabsmanager.xml') + || ! JComponentHelper::isInstalled('com_regularlabsmanager') + || ! JComponentHelper::isEnabled('com_regularlabsmanager') + ) + { + $url = $is_pro + ? 'https://www.regularlabs.com/' . $alias . '/features' + : JRoute::_('index.php?option=com_installer&view=update'); + + return [$url, '']; + } + + $config = JComponentHelper::getParams('com_regularlabsmanager'); + + $key = trim($config->get('key')); + + if ($is_pro && ! $key) + { + return ['index.php?option=com_regularlabsmanager', '']; + } + + jimport('joomla.filesystem.file'); + + Document::loadMainDependencies(); + JHtml::_('behavior.modal'); + + JFactory::getDocument()->addScriptDeclaration( + " + var RLEM_TIMEOUT = " . (int) $config->get('timeout', 5) . "; + var RLEM_TOKEN = '" . JSession::getFormToken() . "'; + " + ); + Document::script('regularlabsmanager/script.min.js', '18.12.3953'); + + $url = 'https://download.regularlabs.com?ext=' . $alias . '&j=3'; + + if ($is_pro) + { + $url .= '&k=' . strtolower(substr($key, 0, 8) . md5(substr($key, 8))); + } + + return ['', 'RegularLabsManager.openModal(\'update\', [\'' . $alias . '\'], [\'' . $url . '\'], true);']; + } + + /** + * Get the extension name and version for the footer + * + * @param $name + * + * @return string + */ + private static function getFooterName($name) + { + $name = JText::_($name); + + if ( ! $version = self::get($name)) + { + return $name; + } + + if (strpos($version, 'PRO') !== false) + { + return $name . ' v' . str_replace('PRO', '', $version) . ' [PRO]'; + } + + if (strpos($version, 'FREE') !== false) + { + return $name . ' v' . str_replace('FREE', '', $version) . ' [FREE]'; + } + + return $name . ' v' . $version; + } + + /** + * Get the review text for the footer + * + * @param $name + * + * @return string + */ + private static function getFooterReview($name) + { + $alias = Extension::getAliasByName($name); + + $jed_url = 'http://regl.io/jed-' . $alias . '#reviews'; + + return StringHelper::html_entity_decoder( + JText::sprintf( + 'RL_JED_REVIEW', + '', + '' + . ' ' + . str_repeat('', 5) + . '' + ) + ); + } + + /** + * Get the Regular Labs logo for the footer + * + * @return string + */ + private static function getFooterLogo() + { + return JText::sprintf( + 'RL_POWERED_BY', + '' + . 'Regular Labs' + . '' + ); + } + + /** + * Get the copyright text for the footer + * + * @return string + */ + private static function getFooterCopyright() + { + return JText::_('RL_COPYRIGHT') . ' © ' . date('Y') . ' Regular Labs - ' . JText::_('RL_ALL_RIGHTS_RESERVED'); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/src/Xml.php b/deployed/regularlabs/libraries/regularlabs/src/Xml.php new file mode 100644 index 00000000..ea66b88e --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/src/Xml.php @@ -0,0 +1,90 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Library; + +defined('_JEXEC') or die; + +use SimpleXMLElement; + +jimport('joomla.filesystem.file'); + +/** + * Class File + * @package RegularLabs\Library + */ +class Xml +{ + /** + * Get an object filled with data from an xml file + * + * @param string $url + * @param string $root + * + * @return object + */ + public static function toObject($url, $root = '') + { + $cache_id = 'xmlToObject_' . $url . '_' . $root; + + if (Cache::has($cache_id)) + { + return Cache::get($cache_id); + } + + if (file_exists($url)) + { + $xml = @new SimpleXMLElement($url, LIBXML_NONET | LIBXML_NOCDATA, 1); + } + else + { + $xml = simplexml_load_string($url, "SimpleXMLElement", LIBXML_NONET | LIBXML_NOCDATA); + } + + if ( ! @count($xml)) + { + return Cache::set( + $cache_id, + (object) [] + ); + } + + if ($root) + { + if ( ! isset($xml->{$root})) + { + return Cache::set( + $cache_id, + (object) [] + ); + } + + $xml = $xml->{$root}; + } + + $json = json_encode($xml); + $xml = json_decode($json); + if (is_null($xml)) + { + $xml = (object) []; + } + + if ($root && isset($xml->{$root})) + { + $xml = $xml->{$root}; + } + + return Cache::set( + $cache_id, + $xml + ); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/vendor/autoload.php b/deployed/regularlabs/libraries/regularlabs/vendor/autoload.php new file mode 100644 index 00000000..a52ca8c1 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/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 = []; + private $prefixDirsPsr4 = []; + private $fallbackDirsPsr4 = []; + + // PSR-0 + private $prefixesPsr0 = []; + private $fallbackDirsPsr0 = []; + + private $useIncludePath = false; + private $classMap = []; + private $classMapAuthoritative = false; + private $missingClasses = []; + private $apcuPrefix; + + public function getPrefixes() + { + if ( ! empty($this->prefixesPsr0)) + { + return call_user_func_array('array_merge', $this->prefixesPsr0); + } + + return []; + } + + 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') && ini_get('apc.enabled') ? $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([$this, 'loadClass'], true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister([$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])) + { + foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) + { + if (0 === strpos($class, $prefix)) + { + foreach ($this->prefixDirsPsr4[$prefix] as $dir) + { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) + { + 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/deployed/regularlabs/libraries/regularlabs/vendor/composer/LICENSE b/deployed/regularlabs/libraries/regularlabs/vendor/composer/LICENSE new file mode 100644 index 00000000..1a281248 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) 2016 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/deployed/regularlabs/libraries/regularlabs/vendor/composer/autoload_classmap.php b/deployed/regularlabs/libraries/regularlabs/vendor/composer/autoload_classmap.php new file mode 100644 index 00000000..903554af --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/vendor/composer/autoload_classmap.php @@ -0,0 +1,8 @@ + [$baseDir . '/src'], +]; diff --git a/deployed/regularlabs/libraries/regularlabs/vendor/composer/autoload_real.php b/deployed/regularlabs/libraries/regularlabs/vendor/composer/autoload_real.php new file mode 100644 index 00000000..08a55588 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/vendor/composer/autoload_real.php @@ -0,0 +1,60 @@ += 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\ComposerStaticInitf9099d81d2e2cf4863a68cf73354cfc1::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); + + return $loader; + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/vendor/composer/autoload_static.php b/deployed/regularlabs/libraries/regularlabs/vendor/composer/autoload_static.php new file mode 100644 index 00000000..ac2cc8b8 --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/vendor/composer/autoload_static.php @@ -0,0 +1,30 @@ + + [ + 'RegularLabs\\Library\\' => 20, + ], + ]; + + public static $prefixDirsPsr4 = [ + 'RegularLabs\\Library\\' => + [ + 0 => __DIR__ . '/../..' . '/src', + ], + ]; + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInitf9099d81d2e2cf4863a68cf73354cfc1::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInitf9099d81d2e2cf4863a68cf73354cfc1::$prefixDirsPsr4; + }, null, ClassLoader::class); + } +} diff --git a/deployed/regularlabs/libraries/regularlabs/vendor/composer/installed.json b/deployed/regularlabs/libraries/regularlabs/vendor/composer/installed.json new file mode 100644 index 00000000..fe51488c --- /dev/null +++ b/deployed/regularlabs/libraries/regularlabs/vendor/composer/installed.json @@ -0,0 +1 @@ +[] diff --git a/deployed/regularlabs/media/advancedmodules/js/frontediting.js b/deployed/regularlabs/media/advancedmodules/js/frontediting.js new file mode 100644 index 00000000..79314074 --- /dev/null +++ b/deployed/regularlabs/media/advancedmodules/js/frontediting.js @@ -0,0 +1,37 @@ +/** + * @package Advanced Module Manager + * @version 7.7.1 + * + * @author Peter van Westen + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +(function($) { + $(document).ready(function() { + // Menu items edit icons: + setTimeout(function() { + $('.jmoddiv[data-jmenuedittip] .nav li,.jmoddiv[data-jmenuedittip].nav li,.jmoddiv[data-jmenuedittip] .nav .nav-child li,.jmoddiv[data-jmenuedittip].nav .nav-child li').on({ + mouseenter: function() { + var itemids = /\bitem-(\d+)\b/.exec($(this).attr('class')); + if (typeof itemids[1] !== 'string') { + return; + } + + setTimeout(function() { + $('a.jfedit-menu').each(function() { + var menuitemEditUrl = $(this).prop('href') + .replace( + /(?:\/administrator)?\/index.php\?option=com_advancedmodules.*?edit([^\d]+).+$/, + '/administrator/index.php?option=com_menus&view=item&layout=edit$1' + itemids[1] + ); + + $(this).prop('href', menuitemEditUrl); + }); + }, 10); + } + }); + }, 1000); + }); +})(jQuery); diff --git a/deployed/regularlabs/media/advancedmodules/js/frontediting.min.js b/deployed/regularlabs/media/advancedmodules/js/frontediting.min.js new file mode 100644 index 00000000..f7ad30b6 --- /dev/null +++ b/deployed/regularlabs/media/advancedmodules/js/frontediting.min.js @@ -0,0 +1,6 @@ +/* + * Copyright © 2018 Regular Labs - All Rights Reserved + * License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ +(function($){$(document).ready(function(){setTimeout(function(){$(".jmoddiv[data-jmenuedittip] .nav li,.jmoddiv[data-jmenuedittip].nav li,.jmoddiv[data-jmenuedittip] .nav .nav-child li,.jmoddiv[data-jmenuedittip].nav .nav-child li").on({mouseenter:function(){var itemids=/\bitem-(\d+)\b/.exec($(this).attr("class"));if(typeof itemids[1]!=="string")return;setTimeout(function(){$("a.jfedit-menu").each(function(){var menuitemEditUrl=$(this).prop("href").replace(/(?:\/administrator)?\/index.php\?option=com_advancedmodules.*?edit([^\d]+).+$/, +"/administrator/index.php?option=com_menus&view=item&layout=edit$1"+itemids[1]);$(this).prop("href",menuitemEditUrl)})},10)}})},1E3)})})(jQuery); diff --git a/deployed/regularlabs/media/modals/css/bootstrap.css b/deployed/regularlabs/media/modals/css/bootstrap.css new file mode 100644 index 00000000..6a14b58b --- /dev/null +++ b/deployed/regularlabs/media/modals/css/bootstrap.css @@ -0,0 +1,293 @@ +/** + * @package Modals + * @version 9.13.0 + * + * @author Peter van Westen + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ +/* + * You can override this stylesheet by creating your own in: + * /templates/[YOUR TEMPLATE]/css/modals/bootstrap.css + */ +/* + * ColorBox Core Style: + * The following CSS is consistent between example themes and should not be altered. + */ +#colorbox, +#cboxOverlay, +#cboxWrapper { + position: absolute; + top: 0; + left: 0; + z-index: 9999; + overflow: hidden; +} +#cboxWrapper { + max-width: none; +} +#cboxOverlay { + position: fixed; + width: 100%; + height: 100%; +} +#cboxMiddleLeft, +#cboxBottomLeft { + clear: left; +} +#cboxContent { + position: relative; +} +#cboxLoadedContent { + overflow: auto; + -webkit-overflow-scrolling: touch; +} +#cboxTitle { + margin: 0; +} +#cboxLoadingOverlay, +#cboxLoadingGraphic { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} +#cboxPrevious, +#cboxNext, +#cboxClose, +#cboxSlideshow { + cursor: pointer; +} +.cboxPhoto { + float: left; + margin: auto; + border: 0; + display: block; + max-width: none; + -ms-interpolation-mode: bicubic; +} +.cboxIframe { + width: 100%; + height: 100%; + display: block; + border: 0; + padding: 0; + margin: 0; +} +#colorbox, +#cboxContent, +#cboxLoadedContent { + box-sizing: content-box; + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; +} +#cboxTitle .modals_description { + font-size: .7em; + font-weight: normal; +} +.modal_link_hidden { + display: none !important; +} +/* + * User Style: + * Change the following styles to modify the appearance of ColorBox. They are + * ordered & tabbed in a way that represents the nesting of the generated HTML. + */ +#cboxOverlay { + background-color: #000; + opacity: 0.8; + filter: alpha(opacity=80); +} +#colorbox { + outline: 0; + top: 50%; + left: 50%; + background-color: #fff; + border: 1px solid #999999; + border: 1px solid rgba(0, 0, 0, 0.3); + *border: 1px solid #999999; + /* IE6-7 */ + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; + margin: 0 !important; +} +#cboxContent { + overflow: hidden; +} +#cboxLoadedContent { + overflow-y: auto; + padding: 15px; + margin-top: 44px; + margin-bottom: 0px; + max-height: none; +} +#cboxTitle { + border-bottom: 1px solid #eeeeee; + position: absolute; + top: 0; + left: 0; + right: 0; + margin: 0; + padding: 9px 25px 9px 15px; + color: inherit; + text-align: left; + text-rendering: optimizelegibility; + font-size: 20px; + line-height: 24px; + font-weight: bold; + min-height: 24px; +} +#cboxTitle small { + font-weight: normal; +} +.cbimg { + border: 0; + font: 0/0 a; + text-shadow: none; + color: transparent; + position: absolute; + width: 14px; + height: 14px; + line-height: 14px; + background: transparent url("../images/bootstrap/controls.png") no-repeat 0 0; + *margin-right: .3em; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +#cboxPrevious, +#cboxNext, +#cboxSlideshow { + border: 0; + font: 0/0 a; + text-shadow: none; + color: transparent; + position: absolute; + width: 14px; + height: 14px; + line-height: 14px; + background: transparent url("../images/bootstrap/controls.png") no-repeat 0 0; + *margin-right: .3em; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + top: 50%; + width: 42px; + height: 44px; +} +#cboxCurrent, +#cboxPrevious, +#cboxNext, +#cboxSlideshow { + position: absolute; + background-color: #fff; + border: 15px solid #fff; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); + -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); + box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); + opacity: 0; + filter: alpha(opacity=0); +} +#cboxContent:hover #cboxCurrent, +#cboxContent:hover #cboxPrevious, +#cboxContent:hover #cboxNext, +#cboxContent:hover #cboxSlideshow { + opacity: 1; + filter: alpha(opacity=100); +} +#cboxCurrent { + font-weight: bold; + line-height: 1em; + bottom: 0; + right: 0; + -webkit-border-radius: 6px 0 6px 0; + -moz-border-radius: 6px 0 6px 0; + border-radius: 6px 0 6px 0; +} +#cboxPrevious { + background-position: 0 0; + left: 0; + -webkit-border-radius: 0 6px 6px 0; + -moz-border-radius: 0 6px 6px 0; + border-radius: 0 6px 6px 0; +} +#cboxNext { + background-position: -24px 0; + right: 0; + -webkit-border-radius: 6px 0 0 6px; + -moz-border-radius: 6px 0 0 6px; + border-radius: 6px 0 0 6px; +} +#cboxSlideshow { + background-position: -48px 0; + left: 50%; + right: 50%; +} +.cboxSlideshow_on #cboxSlideshow { + background-position: -72px 0; +} +#cboxClose { + border: 0; + font: 0/0 a; + text-shadow: none; + color: transparent; + position: absolute; + width: 14px; + height: 14px; + line-height: 14px; + background: transparent url("../images/bootstrap/controls.png") no-repeat 0 0; + *margin-right: .3em; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-position: -96px 0; + top: 14px; + right: 15px; + opacity: 0.3; + filter: alpha(opacity=30); +} +#cboxClose:hover { + opacity: 0.8; + filter: alpha(opacity=80); +} +#cboxLoadingGraphic { + background: transparent url(../images/bootstrap/loading.gif) no-repeat 50% 50%; + opacity: 0.8; + filter: alpha(opacity=80); + height: 100%; +} +.no_title #cboxTitle { + height: 0 !important; + min-height: 0; + padding: 0; +} +.no_title #cboxLoadedContent { + margin-top: 0 !important; +} +.no_title #cboxClose { + right: 3px; + top: 3px; +} +.no_title.has_scrollbar #cboxClose { + right: 18px; +} +#cboxTitle .countdown { + width: 100%; + height: 2px; + position: absolute; + top: 0; + left: 0; + background-color: #049cdb; +} diff --git a/deployed/regularlabs/media/modals/css/bootstrap.min.css b/deployed/regularlabs/media/modals/css/bootstrap.min.css new file mode 100644 index 00000000..dfe6fe86 --- /dev/null +++ b/deployed/regularlabs/media/modals/css/bootstrap.min.css @@ -0,0 +1 @@ +#cboxWrapper,.cboxPhoto{max-width:none}.cboxIframe,.cboxPhoto{display:block;border:0}#cboxClose:hover,#cboxLoadingGraphic,#cboxOverlay{opacity:.8;filter:alpha(opacity=80)}#cboxOverlay,#cboxWrapper,#colorbox{position:absolute;top:0;left:0;z-index:9999;overflow:hidden}#cboxOverlay{position:fixed;width:100%;height:100%;background-color:#000}#cboxBottomLeft,#cboxMiddleLeft{clear:left}#cboxContent{position:relative;overflow:hidden}#cboxLoadingGraphic,#cboxLoadingOverlay{position:absolute;top:0;left:0;width:100%;height:100%}#cboxClose,#cboxNext,#cboxPrevious,#cboxSlideshow{cursor:pointer}.cboxPhoto{float:left;margin:auto;-ms-interpolation-mode:bicubic}.cboxIframe{width:100%;height:100%;padding:0;margin:0}#cboxClose,.cbimg{width:14px;height:14px;position:absolute}#cboxContent,#cboxLoadedContent,#colorbox{box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box}#cboxNext,#cboxPrevious,#cboxSlideshow,.cbimg{background:url(../images/bootstrap/controls.png) no-repeat;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;text-shadow:none;color:transparent;*margin-right:.3em}#cboxTitle .modals_description{font-size:.7em;font-weight:400}.modal_link_hidden{display:none!important}#colorbox{outline:0;top:50%;left:50%;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0,0,0,.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,.3);box-shadow:0 3px 7px rgba(0,0,0,.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;margin:0!important}#cboxLoadedContent{overflow:auto;-webkit-overflow-scrolling:touch;overflow-y:auto;padding:15px;margin-top:44px;margin-bottom:0;max-height:none}#cboxTitle{border-bottom:1px solid #eee;position:absolute;top:0;left:0;right:0;margin:0;padding:9px 25px 9px 15px;color:inherit;text-align:left;text-rendering:optimizelegibility;font-size:20px;line-height:24px;font-weight:700;min-height:24px}#cboxTitle small{font-weight:400}.cbimg{border:0;font:0/0 a;line-height:14px;box-sizing:border-box}#cboxNext,#cboxPrevious,#cboxSlideshow{font:0/0 a;line-height:14px;box-sizing:border-box;top:50%;width:42px;height:44px}#cboxCurrent,#cboxNext,#cboxPrevious,#cboxSlideshow{position:absolute;background-color:#fff;border:15px solid #fff;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 0 10px rgba(0,0,0,.5);-moz-box-shadow:0 0 10px rgba(0,0,0,.5);box-shadow:0 0 10px rgba(0,0,0,.5);opacity:0;filter:alpha(opacity=0)}#cboxContent:hover #cboxCurrent,#cboxContent:hover #cboxNext,#cboxContent:hover #cboxPrevious,#cboxContent:hover #cboxSlideshow{opacity:1;filter:alpha(opacity=100)}#cboxCurrent{font-weight:700;line-height:1em;bottom:0;right:0;-webkit-border-radius:6px 0 6px 0;-moz-border-radius:6px 0;border-radius:6px 0}#cboxPrevious{background-position:0 0;left:0;-webkit-border-radius:0 6px 6px 0;-moz-border-radius:0 6px 6px 0;border-radius:0 6px 6px 0}#cboxNext{background-position:-24px 0;right:0;-webkit-border-radius:6px 0 0 6px;-moz-border-radius:6px 0 0 6px;border-radius:6px 0 0 6px}#cboxSlideshow{background-position:-48px 0;left:50%;right:50%}.cboxSlideshow_on #cboxSlideshow{background-position:-72px 0}#cboxClose{border:0;font:0/0 a;text-shadow:none;color:transparent;line-height:14px;background:url(../images/bootstrap/controls.png) -96px 0 no-repeat;*margin-right:.3em;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;top:14px;right:15px;opacity:.3;filter:alpha(opacity=30)}#cboxLoadingGraphic{background:url(../images/bootstrap/loading.gif) 50% 50% no-repeat;height:100%}.no_title #cboxTitle{height:0!important;min-height:0;padding:0}.no_title #cboxLoadedContent{margin-top:0!important}.no_title #cboxClose{right:3px;top:3px}.no_title.has_scrollbar #cboxClose{right:18px}#cboxTitle .countdown{width:100%;height:2px;position:absolute;top:0;left:0;background-color:#049cdb} \ No newline at end of file diff --git a/deployed/regularlabs/media/modals/css/colorbox1.css b/deployed/regularlabs/media/modals/css/colorbox1.css new file mode 100644 index 00000000..8b73e1a3 --- /dev/null +++ b/deployed/regularlabs/media/modals/css/colorbox1.css @@ -0,0 +1,236 @@ +/* + * ColorBox Core Style: + * The following CSS is consistent between example themes and should not be altered. + */ +#colorbox, +#cboxOverlay, +#cboxWrapper { + position: absolute; + top: 0; + left: 0; + z-index: 9999; + overflow: hidden; +} +#cboxWrapper { + max-width: none; +} +#cboxOverlay { + position: fixed; + width: 100%; + height: 100%; +} +#cboxMiddleLeft, +#cboxBottomLeft { + clear: left; +} +#cboxContent { + position: relative; +} +#cboxLoadedContent { + overflow: auto; + -webkit-overflow-scrolling: touch; +} +#cboxTitle { + margin: 0; +} +#cboxLoadingOverlay, +#cboxLoadingGraphic { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} +#cboxPrevious, +#cboxNext, +#cboxClose, +#cboxSlideshow { + cursor: pointer; +} +.cboxPhoto { + float: left; + margin: auto; + border: 0; + display: block; + max-width: none; + -ms-interpolation-mode: bicubic; +} +.cboxIframe { + width: 100%; + height: 100%; + display: block; + border: 0; + padding: 0; + margin: 0; +} +#colorbox, +#cboxContent, +#cboxLoadedContent { + box-sizing: content-box; + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; +} +#cboxTitle .modals_description { + font-size: .7em; + font-weight: normal; +} +.modal_link_hidden { + display: none !important; +} +/* + User Style: + Change the following styles to modify the appearance of Colorbox. They are + ordered & tabbed in a way that represents the nesting of the generated HTML. +*/ +#cboxOverlay { + background: url(../images/colorbox1/overlay.png) repeat 0 0; +} +#colorbox { + outline: 0; +} +#cboxTopLeft { + width: 21px; + height: 21px; + background: url(../images/colorbox1/controls.png) no-repeat -101px 0; +} +#cboxTopRight { + width: 21px; + height: 21px; + background: url(../images/colorbox1/controls.png) no-repeat -130px 0; +} +#cboxBottomLeft { + width: 21px; + height: 21px; + background: url(../images/colorbox1/controls.png) no-repeat -101px -29px; +} +#cboxBottomRight { + width: 21px; + height: 21px; + background: url(../images/colorbox1/controls.png) no-repeat -130px -29px; +} +#cboxMiddleLeft { + width: 21px; + background: url(../images/colorbox1/controls.png) left top repeat-y; +} +#cboxMiddleRight { + width: 21px; + background: url(../images/colorbox1/controls.png) right top repeat-y; +} +#cboxTopCenter { + height: 21px; + background: url(../images/colorbox1/border.png) 0 0 repeat-x; +} +#cboxBottomCenter { + height: 21px; + background: url(../images/colorbox1/border.png) 0 -29px repeat-x; +} +#cboxContent { + background: #fff; + overflow: hidden; +} +.cboxIframe { + background: #fff; +} +#cboxError { + padding: 50px; + border: 1px solid #ccc; +} +#cboxLoadedContent { + margin-bottom: 28px; +} +#cboxTitle { + position: absolute; + bottom: 4px; + left: 0; + text-align: center; + width: 100%; + color: #949494; +} +#cboxCurrent { + position: absolute; + bottom: 4px; + left: 58px; + color: #949494; +} +#cboxLoadingOverlay { + background: url(../images/colorbox1/loading_background.png) no-repeat center center; +} +#cboxLoadingGraphic { + background: url(../images/colorbox1/loading.gif) no-repeat center center; +} +/* these elements are buttons, and may need to have additional styles reset to avoid unwanted base styles */ +#cboxPrevious, +#cboxNext, +#cboxSlideshow, +#cboxClose { + border: 0; + padding: 0; + margin: 0; + overflow: visible; + width: auto; + background: none; +} +/* avoid outlines on :active (mouseclick), but preserve outlines on :focus (tabbed navigating) */ +#cboxPrevious:active, +#cboxNext:active, +#cboxSlideshow:active, +#cboxClose:active { + outline: 0; +} +#cboxSlideshow { + position: absolute; + bottom: 4px; + right: 30px; + color: #0092ef; +} +#cboxPrevious { + position: absolute; + bottom: 0; + left: 0; + background: url(../images/colorbox1/controls.png) no-repeat -75px 0; + width: 25px; + height: 25px; + text-indent: -9999px; +} +#cboxPrevious:hover { + background-position: -75px -25px; +} +#cboxNext { + position: absolute; + bottom: 0; + left: 27px; + background: url(../images/colorbox1/controls.png) no-repeat -50px 0; + width: 25px; + height: 25px; + text-indent: -9999px; +} +#cboxNext:hover { + background-position: -50px -25px; +} +#cboxClose { + position: absolute; + bottom: 0; + right: 0; + background: url(../images/colorbox1/controls.png) no-repeat -25px 0; + width: 25px; + height: 25px; + text-indent: -9999px; +} +#cboxClose:hover { + background-position: -25px -25px; +} +/* + The following fixes a problem where IE7 and IE8 replace a PNG's alpha transparency with a black fill + when an alpha filter (opacity change) is set on the element or ancestor element. This style is not applied to or needed in IE9. + See: http://jacklmoore.com/notes/ie-transparency-problems/ +*/ +.cboxIE #cboxTopLeft, +.cboxIE #cboxTopCenter, +.cboxIE #cboxTopRight, +.cboxIE #cboxBottomLeft, +.cboxIE #cboxBottomCenter, +.cboxIE #cboxBottomRight, +.cboxIE #cboxMiddleLeft, +.cboxIE #cboxMiddleRight { + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00FFFFFF', endColorstr='#00FFFFFF'); +} diff --git a/deployed/regularlabs/media/modals/css/colorbox1.min.css b/deployed/regularlabs/media/modals/css/colorbox1.min.css new file mode 100644 index 00000000..afeb5e20 --- /dev/null +++ b/deployed/regularlabs/media/modals/css/colorbox1.min.css @@ -0,0 +1 @@ +#cboxWrapper,.cboxPhoto{max-width:none}.cboxIframe,.cboxPhoto{display:block;border:0}#cboxCurrent,#cboxTitle{position:absolute;color:#949494;bottom:4px}#cboxClose:active,#cboxNext:active,#cboxPrevious:active,#cboxSlideshow:active,#colorbox{outline:0}#cboxOverlay,#cboxWrapper,#colorbox{position:absolute;top:0;left:0;z-index:9999;overflow:hidden}#cboxOverlay{position:fixed;width:100%;height:100%;background:url(../images/colorbox1/overlay.png)}#cboxBottomLeft,#cboxMiddleLeft{clear:left}#cboxContent{position:relative;background:#fff;overflow:hidden}#cboxTitle{margin:0;left:0;text-align:center;width:100%}#cboxLoadingGraphic,#cboxLoadingOverlay{position:absolute;top:0;left:0;width:100%;height:100%}.cboxPhoto{float:left;margin:auto;-ms-interpolation-mode:bicubic}.cboxIframe{width:100%;height:100%;padding:0;margin:0}#cboxContent,#cboxLoadedContent,#colorbox{box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box}#cboxTitle .modals_description{font-size:.7em;font-weight:400}.modal_link_hidden{display:none!important}#cboxTopLeft{width:21px;height:21px;background:url(../images/colorbox1/controls.png) -101px 0 no-repeat}#cboxTopRight{width:21px;height:21px;background:url(../images/colorbox1/controls.png) -130px 0 no-repeat}#cboxBottomLeft{width:21px;height:21px;background:url(../images/colorbox1/controls.png) -101px -29px no-repeat}#cboxBottomRight{width:21px;height:21px;background:url(../images/colorbox1/controls.png) -130px -29px no-repeat}#cboxMiddleLeft{width:21px;background:url(../images/colorbox1/controls.png) left top repeat-y}#cboxMiddleRight{width:21px;background:url(../images/colorbox1/controls.png) right top repeat-y}#cboxTopCenter{height:21px;background:url(../images/colorbox1/border.png) repeat-x}#cboxBottomCenter{height:21px;background:url(../images/colorbox1/border.png) 0 -29px repeat-x}.cboxIframe{background:#fff}#cboxError{padding:50px;border:1px solid #ccc}#cboxLoadedContent{overflow:auto;-webkit-overflow-scrolling:touch;margin-bottom:28px}#cboxCurrent{left:58px}#cboxLoadingOverlay{background:url(../images/colorbox1/loading_background.png) center center no-repeat}#cboxLoadingGraphic{background:url(../images/colorbox1/loading.gif) center center no-repeat}#cboxClose,#cboxNext,#cboxPrevious,#cboxSlideshow{cursor:pointer;border:0;padding:0;margin:0;overflow:visible;width:auto;background:0 0}#cboxClose,#cboxNext,#cboxPrevious{position:absolute;bottom:0;width:25px;height:25px;text-indent:-9999px}#cboxSlideshow{position:absolute;bottom:4px;right:30px;color:#0092ef}#cboxPrevious{left:0;background:url(../images/colorbox1/controls.png) -75px 0 no-repeat}#cboxPrevious:hover{background-position:-75px -25px}#cboxNext{left:27px;background:url(../images/colorbox1/controls.png) -50px 0 no-repeat}#cboxNext:hover{background-position:-50px -25px}#cboxClose{right:0;background:url(../images/colorbox1/controls.png) -25px 0 no-repeat}#cboxClose:hover{background-position:-25px -25px}.cboxIE #cboxBottomCenter,.cboxIE #cboxBottomLeft,.cboxIE #cboxBottomRight,.cboxIE #cboxMiddleLeft,.cboxIE #cboxMiddleRight,.cboxIE #cboxTopCenter,.cboxIE #cboxTopLeft,.cboxIE #cboxTopRight{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00FFFFFF', endColorstr='#00FFFFFF')} \ No newline at end of file diff --git a/deployed/regularlabs/media/modals/css/colorbox2.css b/deployed/regularlabs/media/modals/css/colorbox2.css new file mode 100644 index 00000000..efa5136b --- /dev/null +++ b/deployed/regularlabs/media/modals/css/colorbox2.css @@ -0,0 +1,192 @@ +/* + * ColorBox Core Style: + * The following CSS is consistent between example themes and should not be altered. + */ +#colorbox, +#cboxOverlay, +#cboxWrapper { + position: absolute; + top: 0; + left: 0; + z-index: 9999; + overflow: hidden; +} +#cboxWrapper { + max-width: none; +} +#cboxOverlay { + position: fixed; + width: 100%; + height: 100%; +} +#cboxMiddleLeft, +#cboxBottomLeft { + clear: left; +} +#cboxContent { + position: relative; +} +#cboxLoadedContent { + overflow: auto; + -webkit-overflow-scrolling: touch; +} +#cboxTitle { + margin: 0; +} +#cboxLoadingOverlay, +#cboxLoadingGraphic { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} +#cboxPrevious, +#cboxNext, +#cboxClose, +#cboxSlideshow { + cursor: pointer; +} +.cboxPhoto { + float: left; + margin: auto; + border: 0; + display: block; + max-width: none; + -ms-interpolation-mode: bicubic; +} +.cboxIframe { + width: 100%; + height: 100%; + display: block; + border: 0; + padding: 0; + margin: 0; +} +#colorbox, +#cboxContent, +#cboxLoadedContent { + box-sizing: content-box; + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; +} +#cboxTitle .modals_description { + font-size: .7em; + font-weight: normal; +} +.modal_link_hidden { + display: none !important; +} +/* + User Style: + Change the following styles to modify the appearance of Colorbox. They are + ordered & tabbed in a way that represents the nesting of the generated HTML. +*/ +#cboxOverlay { + background: #fff; +} +#colorbox { + outline: 0; +} +#cboxContent { + margin-top: 32px; + overflow: visible; + background: #000; +} +.cboxIframe { + background: #fff; +} +#cboxError { + padding: 50px; + border: 1px solid #ccc; +} +#cboxLoadedContent { + background: #000; + padding: 6px 12px; + color: #fff; +} +#colorbox.is_image #cboxLoadedContent, +#colorbox.is_video #cboxLoadedContent { + padding: 0; +} +#cboxLoadingGraphic { + background: url(../images/colorbox2/loading.gif) no-repeat center center; +} +#cboxLoadingOverlay { + background: #000; +} +#cboxTitle { + position: absolute; + top: -22px; + left: 0; + color: #000; + background: #fff; +} +#cboxCurrent { + position: absolute; + top: -22px; + right: 205px; + text-indent: -9999px; +} +/* these elements are buttons, and may need to have additional styles reset to avoid unwanted base styles */ +#cboxPrevious, +#cboxNext, +#cboxSlideshow, +#cboxClose { + border: 0; + padding: 0; + margin: 0; + overflow: visible; + text-indent: -9999px; + width: 20px; + height: 20px; + position: absolute; + top: -20px; + background: url(../images/colorbox2/controls.png) no-repeat 0 0; +} +/* avoid outlines on :active (mouseclick), but preserve outlines on :focus (tabbed navigating) */ +#cboxPrevious:active, +#cboxNext:active, +#cboxSlideshow:active, +#cboxClose:active { + outline: 0; +} +#cboxPrevious { + background-position: 0px 0px; + right: 44px; +} +#cboxPrevious:hover { + background-position: 0px -25px; +} +#cboxNext { + background-position: -25px 0px; + right: 22px; +} +#cboxNext:hover { + background-position: -25px -25px; +} +#cboxClose { + background-position: -50px 0px; + right: 0; +} +#cboxClose:hover { + background-position: -50px -25px; +} +.cboxSlideshow_on #cboxPrevious, +.cboxSlideshow_off #cboxPrevious { + right: 66px; +} +.cboxSlideshow_on #cboxSlideshow { + background-position: -75px -25px; + right: 44px; +} +.cboxSlideshow_on #cboxSlideshow:hover { + background-position: -100px -25px; +} +.cboxSlideshow_off #cboxSlideshow { + background-position: -100px 0px; + right: 44px; +} +.cboxSlideshow_off #cboxSlideshow:hover { + background-position: -75px -25px; +} diff --git a/deployed/regularlabs/media/modals/css/colorbox2.min.css b/deployed/regularlabs/media/modals/css/colorbox2.min.css new file mode 100644 index 00000000..3a54f5b5 --- /dev/null +++ b/deployed/regularlabs/media/modals/css/colorbox2.min.css @@ -0,0 +1 @@ +#cboxWrapper,.cboxPhoto{max-width:none}.cboxIframe,.cboxPhoto{display:block;border:0}#cboxCurrent,#cboxTitle{top:-22px;position:absolute}#cboxClose:active,#cboxNext:active,#cboxPrevious:active,#cboxSlideshow:active,#colorbox{outline:0}#cboxOverlay,#cboxWrapper,#colorbox{position:absolute;top:0;left:0;z-index:9999;overflow:hidden}#cboxOverlay{position:fixed;width:100%;height:100%;background:#fff}#cboxBottomLeft,#cboxMiddleLeft{clear:left}#cboxTitle{margin:0;left:0;color:#000;background:#fff}#cboxLoadingGraphic,#cboxLoadingOverlay{position:absolute;top:0;left:0;width:100%;height:100%}.cboxPhoto{float:left;margin:auto;-ms-interpolation-mode:bicubic}.cboxIframe{width:100%;height:100%;padding:0;margin:0}#cboxContent,#cboxLoadedContent,#colorbox{box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box}#cboxTitle .modals_description{font-size:.7em;font-weight:400}.modal_link_hidden{display:none!important}#cboxContent{position:relative;margin-top:32px;overflow:visible;background:#000}.cboxIframe{background:#fff}#cboxError{padding:50px;border:1px solid #ccc}#cboxLoadedContent{overflow:auto;-webkit-overflow-scrolling:touch;background:#000;padding:6px 12px;color:#fff}#colorbox.is_image #cboxLoadedContent,#colorbox.is_video #cboxLoadedContent{padding:0}#cboxLoadingGraphic{background:url(../images/colorbox2/loading.gif) center center no-repeat}#cboxLoadingOverlay{background:#000}#cboxCurrent{right:205px;text-indent:-9999px}#cboxClose,#cboxNext,#cboxPrevious,#cboxSlideshow{cursor:pointer;border:0;padding:0;margin:0;overflow:visible;text-indent:-9999px;width:20px;height:20px;position:absolute;top:-20px;background:url(../images/colorbox2/controls.png) no-repeat}#cboxPrevious{background-position:0 0;right:44px}#cboxPrevious:hover{background-position:0 -25px}#cboxNext{background-position:-25px 0;right:22px}#cboxNext:hover{background-position:-25px -25px}#cboxClose{background-position:-50px 0;right:0}#cboxClose:hover{background-position:-50px -25px}.cboxSlideshow_off #cboxPrevious,.cboxSlideshow_on #cboxPrevious{right:66px}.cboxSlideshow_on #cboxSlideshow{background-position:-75px -25px;right:44px}.cboxSlideshow_on #cboxSlideshow:hover{background-position:-100px -25px}.cboxSlideshow_off #cboxSlideshow{background-position:-100px 0;right:44px}.cboxSlideshow_off #cboxSlideshow:hover{background-position:-75px -25px} \ No newline at end of file diff --git a/deployed/regularlabs/media/modals/css/colorbox3.css b/deployed/regularlabs/media/modals/css/colorbox3.css new file mode 100644 index 00000000..58c1a623 --- /dev/null +++ b/deployed/regularlabs/media/modals/css/colorbox3.css @@ -0,0 +1,192 @@ +/* + * ColorBox Core Style: + * The following CSS is consistent between example themes and should not be altered. + */ +#colorbox, +#cboxOverlay, +#cboxWrapper { + position: absolute; + top: 0; + left: 0; + z-index: 9999; + overflow: hidden; +} +#cboxWrapper { + max-width: none; +} +#cboxOverlay { + position: fixed; + width: 100%; + height: 100%; +} +#cboxMiddleLeft, +#cboxBottomLeft { + clear: left; +} +#cboxContent { + position: relative; +} +#cboxLoadedContent { + overflow: auto; + -webkit-overflow-scrolling: touch; +} +#cboxTitle { + margin: 0; +} +#cboxLoadingOverlay, +#cboxLoadingGraphic { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} +#cboxPrevious, +#cboxNext, +#cboxClose, +#cboxSlideshow { + cursor: pointer; +} +.cboxPhoto { + float: left; + margin: auto; + border: 0; + display: block; + max-width: none; + -ms-interpolation-mode: bicubic; +} +.cboxIframe { + width: 100%; + height: 100%; + display: block; + border: 0; + padding: 0; + margin: 0; +} +#colorbox, +#cboxContent, +#cboxLoadedContent { + box-sizing: content-box; + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; +} +#cboxTitle .modals_description { + font-size: .7em; + font-weight: normal; +} +.modal_link_hidden { + display: none !important; +} +/* + User Style: + Change the following styles to modify the appearance of Colorbox. They are + ordered & tabbed in a way that represents the nesting of the generated HTML. +*/ +#cboxOverlay { + background: #000; +} +#colorbox { + outline: 0; +} +#cboxContent { + margin-top: 20px; + background: #000; +} +.cboxIframe { + background: #fff; +} +#cboxError { + padding: 50px; + border: 1px solid #ccc; +} +#cboxLoadedContent { + border: 5px solid #000; + padding: 6px 12px; + background: #fff; +} +#colorbox.is_image #cboxLoadedContent, +#colorbox.is_video #cboxLoadedContent { + padding: 0; +} +#cboxTitle { + position: absolute; + top: -20px; + left: 0; + color: #ccc; +} +#cboxCurrent { + position: absolute; + top: -20px; + right: 0px; + color: #ccc; +} +#cboxLoadingGraphic { + background: url(../images/colorbox3/loading.gif) no-repeat center center; +} +/* these elements are buttons, and may need to have additional styles reset to avoid unwanted base styles */ +#cboxPrevious, +#cboxNext, +#cboxSlideshow, +#cboxClose { + border: 0; + padding: 0; + margin: 0; + overflow: visible; + width: auto; + background: none; +} +/* avoid outlines on :active (mouseclick), but preserve outlines on :focus (tabbed navigating) */ +#cboxPrevious:active, +#cboxNext:active, +#cboxSlideshow:active, +#cboxClose:active { + outline: 0; +} +#cboxSlideshow { + position: absolute; + top: -20px; + right: 90px; + color: #fff; +} +#cboxPrevious { + position: absolute; + top: 50%; + left: 5px; + margin-top: -32px; + background: url(../images/colorbox3/controls.png) no-repeat top left; + width: 28px; + height: 65px; + text-indent: -9999px; +} +#cboxPrevious:hover { + background-position: bottom left; +} +#cboxNext { + position: absolute; + top: 50%; + right: 5px; + margin-top: -32px; + background: url(../images/colorbox3/controls.png) no-repeat top right; + width: 28px; + height: 65px; + text-indent: -9999px; +} +#cboxNext:hover { + background-position: bottom right; +} +#cboxClose { + position: absolute; + top: 5px; + right: 5px; + display: block; + background: url(../images/colorbox3/controls.png) no-repeat top center; + width: 38px; + height: 19px; + text-indent: -9999px; +} +#cboxClose:hover { + background-position: bottom center; +} +#colorbox.has_scrollbar #cboxClose { + right: 16px; +} diff --git a/deployed/regularlabs/media/modals/css/colorbox3.min.css b/deployed/regularlabs/media/modals/css/colorbox3.min.css new file mode 100644 index 00000000..ec2e7b39 --- /dev/null +++ b/deployed/regularlabs/media/modals/css/colorbox3.min.css @@ -0,0 +1 @@ +#cboxWrapper,.cboxPhoto{max-width:none}.cboxIframe,.cboxPhoto{display:block;border:0}#cboxCurrent,#cboxTitle{position:absolute;color:#ccc;top:-20px}#cboxClose:active,#cboxNext:active,#cboxPrevious:active,#cboxSlideshow:active,#colorbox{outline:0}#cboxOverlay,#cboxWrapper,#colorbox{position:absolute;top:0;left:0;z-index:9999;overflow:hidden}#cboxOverlay{position:fixed;width:100%;height:100%;background:#000}#cboxBottomLeft,#cboxMiddleLeft{clear:left}#cboxTitle{margin:0;left:0}#cboxLoadingGraphic,#cboxLoadingOverlay{position:absolute;top:0;left:0;width:100%;height:100%}.cboxPhoto{float:left;margin:auto;-ms-interpolation-mode:bicubic}.cboxIframe{width:100%;height:100%;padding:0;margin:0}#cboxContent,#cboxLoadedContent,#colorbox{box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box}#cboxTitle .modals_description{font-size:.7em;font-weight:400}.modal_link_hidden{display:none!important}#cboxContent{position:relative;margin-top:20px;background:#000}.cboxIframe{background:#fff}#cboxError{padding:50px;border:1px solid #ccc}#cboxLoadedContent{overflow:auto;-webkit-overflow-scrolling:touch;border:5px solid #000;padding:6px 12px;background:#fff}#colorbox.is_image #cboxLoadedContent,#colorbox.is_video #cboxLoadedContent{padding:0}#cboxCurrent{right:0}#cboxLoadingGraphic{background:url(../images/colorbox3/loading.gif) center center no-repeat}#cboxClose,#cboxNext,#cboxPrevious,#cboxSlideshow{cursor:pointer;border:0;padding:0;margin:0;overflow:visible;width:auto;background:0 0}#cboxNext,#cboxPrevious{top:50%;margin-top:-32px;width:28px;height:65px;position:absolute;text-indent:-9999px}#cboxSlideshow{position:absolute;top:-20px;right:90px;color:#fff}#cboxPrevious{left:5px;background:url(../images/colorbox3/controls.png) top left no-repeat}#cboxPrevious:hover{background-position:bottom left}#cboxNext{right:5px;background:url(../images/colorbox3/controls.png) top right no-repeat}#cboxNext:hover{background-position:bottom right}#cboxClose{position:absolute;top:5px;right:5px;display:block;background:url(../images/colorbox3/controls.png) top center no-repeat;width:38px;height:19px;text-indent:-9999px}#cboxClose:hover{background-position:bottom center}#colorbox.has_scrollbar #cboxClose{right:16px} \ No newline at end of file diff --git a/deployed/regularlabs/media/modals/css/colorbox4.css b/deployed/regularlabs/media/modals/css/colorbox4.css new file mode 100644 index 00000000..e0fa5d4d --- /dev/null +++ b/deployed/regularlabs/media/modals/css/colorbox4.css @@ -0,0 +1,216 @@ +/* + * ColorBox Core Style: + * The following CSS is consistent between example themes and should not be altered. + */ +#colorbox, +#cboxOverlay, +#cboxWrapper { + position: absolute; + top: 0; + left: 0; + z-index: 9999; + overflow: hidden; +} +#cboxWrapper { + max-width: none; +} +#cboxOverlay { + position: fixed; + width: 100%; + height: 100%; +} +#cboxMiddleLeft, +#cboxBottomLeft { + clear: left; +} +#cboxContent { + position: relative; +} +#cboxLoadedContent { + overflow: auto; + -webkit-overflow-scrolling: touch; +} +#cboxTitle { + margin: 0; +} +#cboxLoadingOverlay, +#cboxLoadingGraphic { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} +#cboxPrevious, +#cboxNext, +#cboxClose, +#cboxSlideshow { + cursor: pointer; +} +.cboxPhoto { + float: left; + margin: auto; + border: 0; + display: block; + max-width: none; + -ms-interpolation-mode: bicubic; +} +.cboxIframe { + width: 100%; + height: 100%; + display: block; + border: 0; + padding: 0; + margin: 0; +} +#colorbox, +#cboxContent, +#cboxLoadedContent { + box-sizing: content-box; + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; +} +#cboxTitle .modals_description { + font-size: .7em; + font-weight: normal; +} +.modal_link_hidden { + display: none !important; +} +/* + User Style: + Change the following styles to modify the appearance of Colorbox. They are + ordered & tabbed in a way that represents the nesting of the generated HTML. +*/ +#cboxOverlay { + background: #fff; +} +#colorbox { + outline: 0; +} +#cboxTopLeft { + width: 25px; + height: 25px; + background: url(../images/colorbox4/border1.png) no-repeat 0 0; +} +#cboxTopCenter { + height: 25px; + background: url(../images/colorbox4/border1.png) repeat-x 0 -50px; +} +#cboxTopRight { + width: 25px; + height: 25px; + background: url(../images/colorbox4/border1.png) no-repeat -25px 0; +} +#cboxBottomLeft { + width: 25px; + height: 25px; + background: url(../images/colorbox4/border1.png) no-repeat 0 -25px; +} +#cboxBottomCenter { + height: 25px; + background: url(../images/colorbox4/border1.png) repeat-x 0 -75px; +} +#cboxBottomRight { + width: 25px; + height: 25px; + background: url(../images/colorbox4/border1.png) no-repeat -25px -25px; +} +#cboxMiddleLeft { + width: 25px; + background: url(../images/colorbox4/border2.png) repeat-y 0 0; +} +#cboxMiddleRight { + width: 25px; + background: url(../images/colorbox4/border2.png) repeat-y -25px 0; +} +#cboxContent { + background: #fff; + overflow: hidden; +} +.cboxIframe { + background: #fff; +} +#cboxError { + padding: 50px; + border: 1px solid #ccc; +} +#cboxLoadedContent { + margin-bottom: 20px; +} +#cboxTitle { + position: absolute; + bottom: 0px; + left: 0; + text-align: center; + width: 100%; + color: #999; +} +#cboxCurrent { + position: absolute; + bottom: 0px; + left: 100px; + color: #999; +} +#cboxLoadingOverlay { + background: #fff url(../images/colorbox4/loading.gif) no-repeat 5px 5px; +} +/* these elements are buttons, and may need to have additional styles reset to avoid unwanted base styles */ +#cboxPrevious, +#cboxNext, +#cboxSlideshow, +#cboxClose { + border: 0; + padding: 0; + margin: 0; + overflow: visible; + width: auto; + background: none; +} +/* avoid outlines on :active (mouseclick), but preserve outlines on :focus (tabbed navigating) */ +#cboxPrevious:active, +#cboxNext:active, +#cboxSlideshow:active, +#cboxClose:active { + outline: 0; +} +#cboxSlideshow { + position: absolute; + bottom: 0px; + right: 42px; + color: #444; +} +#cboxPrevious { + position: absolute; + bottom: 0px; + left: 0; + color: #444; +} +#cboxNext { + position: absolute; + bottom: 0px; + left: 63px; + color: #444; +} +#cboxClose { + position: absolute; + bottom: 0; + right: 0; + display: block; + color: #444; +} +/* + The following fixes a problem where IE7 and IE8 replace a PNG's alpha transparency with a black fill + when an alpha filter (opacity change) is set on the element or ancestor element. This style is not applied to or needed in IE9. + See: http://jacklmoore.com/notes/ie-transparency-problems/ +*/ +.cboxIE #cboxTopLeft, +.cboxIE #cboxTopCenter, +.cboxIE #cboxTopRight, +.cboxIE #cboxBottomLeft, +.cboxIE #cboxBottomCenter, +.cboxIE #cboxBottomRight, +.cboxIE #cboxMiddleLeft, +.cboxIE #cboxMiddleRight { + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00FFFFFF', endColorstr='#00FFFFFF'); +} diff --git a/deployed/regularlabs/media/modals/css/colorbox4.min.css b/deployed/regularlabs/media/modals/css/colorbox4.min.css new file mode 100644 index 00000000..5b512d72 --- /dev/null +++ b/deployed/regularlabs/media/modals/css/colorbox4.min.css @@ -0,0 +1 @@ +#cboxWrapper,.cboxPhoto{max-width:none}.cboxIframe,.cboxPhoto{display:block;border:0}#cboxClose:active,#cboxNext:active,#cboxPrevious:active,#cboxSlideshow:active,#colorbox{outline:0}#cboxClose,#cboxNext,#cboxPrevious,#cboxSlideshow{position:absolute;bottom:0;color:#444}#cboxOverlay,#cboxWrapper,#colorbox{position:absolute;top:0;left:0;z-index:9999;overflow:hidden}#cboxOverlay{position:fixed;width:100%;height:100%;background:#fff}#cboxBottomLeft,#cboxMiddleLeft{clear:left}#cboxContent{position:relative;background:#fff;overflow:hidden}#cboxTitle{margin:0;position:absolute;bottom:0;left:0;text-align:center;width:100%;color:#999}#cboxLoadingGraphic,#cboxLoadingOverlay{position:absolute;top:0;left:0;width:100%;height:100%}.cboxPhoto{float:left;margin:auto;-ms-interpolation-mode:bicubic}.cboxIframe{width:100%;height:100%;padding:0;margin:0}#cboxContent,#cboxLoadedContent,#colorbox{box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box}#cboxTitle .modals_description{font-size:.7em;font-weight:400}.modal_link_hidden{display:none!important}#cboxTopLeft{width:25px;height:25px;background:url(../images/colorbox4/border1.png) no-repeat}#cboxTopCenter{height:25px;background:url(../images/colorbox4/border1.png) 0 -50px repeat-x}#cboxTopRight{width:25px;height:25px;background:url(../images/colorbox4/border1.png) -25px 0 no-repeat}#cboxBottomLeft{width:25px;height:25px;background:url(../images/colorbox4/border1.png) 0 -25px no-repeat}#cboxBottomCenter{height:25px;background:url(../images/colorbox4/border1.png) 0 -75px repeat-x}#cboxBottomRight{width:25px;height:25px;background:url(../images/colorbox4/border1.png) -25px -25px no-repeat}#cboxMiddleLeft{width:25px;background:url(../images/colorbox4/border2.png) repeat-y}#cboxMiddleRight{width:25px;background:url(../images/colorbox4/border2.png) -25px 0 repeat-y}.cboxIframe{background:#fff}#cboxError{padding:50px;border:1px solid #ccc}#cboxLoadedContent{overflow:auto;-webkit-overflow-scrolling:touch;margin-bottom:20px}#cboxCurrent{position:absolute;bottom:0;left:100px;color:#999}#cboxLoadingOverlay{background:url(../images/colorbox4/loading.gif) 5px 5px no-repeat #fff}#cboxClose,#cboxNext,#cboxPrevious,#cboxSlideshow{cursor:pointer;border:0;padding:0;margin:0;overflow:visible;width:auto;background:0 0}#cboxSlideshow{right:42px}#cboxPrevious{left:0}#cboxNext{left:63px}#cboxClose{right:0;display:block}.cboxIE #cboxBottomCenter,.cboxIE #cboxBottomLeft,.cboxIE #cboxBottomRight,.cboxIE #cboxMiddleLeft,.cboxIE #cboxMiddleRight,.cboxIE #cboxTopCenter,.cboxIE #cboxTopLeft,.cboxIE #cboxTopRight{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00FFFFFF', endColorstr='#00FFFFFF')} \ No newline at end of file diff --git a/deployed/regularlabs/media/modals/css/colorbox5.css b/deployed/regularlabs/media/modals/css/colorbox5.css new file mode 100644 index 00000000..fdbc52bf --- /dev/null +++ b/deployed/regularlabs/media/modals/css/colorbox5.css @@ -0,0 +1,221 @@ +/* + * ColorBox Core Style: + * The following CSS is consistent between example themes and should not be altered. + */ +#colorbox, +#cboxOverlay, +#cboxWrapper { + position: absolute; + top: 0; + left: 0; + z-index: 9999; + overflow: hidden; +} +#cboxWrapper { + max-width: none; +} +#cboxOverlay { + position: fixed; + width: 100%; + height: 100%; +} +#cboxMiddleLeft, +#cboxBottomLeft { + clear: left; +} +#cboxContent { + position: relative; +} +#cboxLoadedContent { + overflow: auto; + -webkit-overflow-scrolling: touch; +} +#cboxTitle { + margin: 0; +} +#cboxLoadingOverlay, +#cboxLoadingGraphic { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} +#cboxPrevious, +#cboxNext, +#cboxClose, +#cboxSlideshow { + cursor: pointer; +} +.cboxPhoto { + float: left; + margin: auto; + border: 0; + display: block; + max-width: none; + -ms-interpolation-mode: bicubic; +} +.cboxIframe { + width: 100%; + height: 100%; + display: block; + border: 0; + padding: 0; + margin: 0; +} +#colorbox, +#cboxContent, +#cboxLoadedContent { + box-sizing: content-box; + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; +} +#cboxTitle .modals_description { + font-size: .7em; + font-weight: normal; +} +.modal_link_hidden { + display: none !important; +} +/* + User Style: + Change the following styles to modify the appearance of Colorbox. They are + ordered & tabbed in a way that represents the nesting of the generated HTML. +*/ +#cboxOverlay { + background: #000; +} +#colorbox { + outline: 0; +} +#cboxTopLeft { + width: 14px; + height: 14px; + background: url(../images/colorbox5/controls.png) no-repeat 0 0; +} +#cboxTopCenter { + height: 14px; + background: url(../images/colorbox5/border.png) repeat-x top left; +} +#cboxTopRight { + width: 14px; + height: 14px; + background: url(../images/colorbox5/controls.png) no-repeat -36px 0; +} +#cboxBottomLeft { + width: 14px; + height: 43px; + background: url(../images/colorbox5/controls.png) no-repeat 0 -32px; +} +#cboxBottomCenter { + height: 43px; + background: url(../images/colorbox5/border.png) repeat-x bottom left; +} +#cboxBottomRight { + width: 14px; + height: 43px; + background: url(../images/colorbox5/controls.png) no-repeat -36px -32px; +} +#cboxMiddleLeft { + width: 14px; + background: url(../images/colorbox5/controls.png) repeat-y -175px 0; +} +#cboxMiddleRight { + width: 14px; + background: url(../images/colorbox5/controls.png) repeat-y -211px 0; +} +#cboxContent { + background: #fff; + overflow: visible; +} +.cboxIframe { + background: #fff; +} +#cboxError { + padding: 50px; + border: 1px solid #ccc; +} +#cboxLoadedContent { + margin-bottom: 5px; +} +#cboxLoadingOverlay { + background: url(../images/colorbox5/loading_background.png) no-repeat center center; +} +#cboxLoadingGraphic { + background: url(../images/colorbox5/loading.gif) no-repeat center center; +} +#cboxTitle { + position: absolute; + bottom: -25px; + left: 0; + text-align: center; + width: 100%; + font-weight: bold; + color: #7C7C7C; + background: #e9e8e8; +} +#cboxCurrent { + position: absolute; + bottom: -25px; + left: 58px; + font-weight: bold; + color: #7C7C7C; +} +/* these elements are buttons, and may need to have additional styles reset to avoid unwanted base styles */ +#cboxPrevious, +#cboxNext, +#cboxSlideshow, +#cboxClose { + border: 0; + padding: 0; + margin: 0; + overflow: visible; + position: absolute; + bottom: -29px; + background: url(../images/colorbox5/controls.png) no-repeat 0px 0px; + width: 23px; + height: 23px; + text-indent: -9999px; +} +/* avoid outlines on :active (mouseclick), but preserve outlines on :focus (tabbed navigating) */ +#cboxPrevious:active, +#cboxNext:active, +#cboxSlideshow:active, +#cboxClose:active { + outline: 0; +} +#cboxPrevious { + left: 0px; + background-position: -51px -25px; +} +#cboxPrevious:hover { + background-position: -51px 0px; +} +#cboxNext { + left: 27px; + background-position: -75px -25px; +} +#cboxNext:hover { + background-position: -75px 0px; +} +#cboxClose { + right: 0; + background-position: -100px -25px; +} +#cboxClose:hover { + background-position: -100px 0px; +} +.cboxSlideshow_on #cboxSlideshow { + background-position: -125px 0px; + right: 27px; +} +.cboxSlideshow_on #cboxSlideshow:hover { + background-position: -150px 0px; +} +.cboxSlideshow_off #cboxSlideshow { + background-position: -150px -25px; + right: 27px; +} +.cboxSlideshow_off #cboxSlideshow:hover { + background-position: -125px 0px; +} diff --git a/deployed/regularlabs/media/modals/css/colorbox5.min.css b/deployed/regularlabs/media/modals/css/colorbox5.min.css new file mode 100644 index 00000000..ed85ab38 --- /dev/null +++ b/deployed/regularlabs/media/modals/css/colorbox5.min.css @@ -0,0 +1 @@ +#cboxWrapper,.cboxPhoto{max-width:none}.cboxIframe,.cboxPhoto{display:block;border:0}#cboxClose:active,#cboxNext:active,#cboxPrevious:active,#cboxSlideshow:active,#colorbox{outline:0}#cboxOverlay,#cboxWrapper,#colorbox{position:absolute;top:0;left:0;z-index:9999;overflow:hidden}#cboxOverlay{position:fixed;width:100%;height:100%;background:#000}#cboxBottomLeft,#cboxMiddleLeft{clear:left}#cboxContent{position:relative;background:#fff;overflow:visible}#cboxTitle{margin:0}#cboxLoadingGraphic,#cboxLoadingOverlay{position:absolute;top:0;left:0;width:100%;height:100%}.cboxPhoto{float:left;margin:auto;-ms-interpolation-mode:bicubic}.cboxIframe{width:100%;height:100%;padding:0;margin:0}#cboxContent,#cboxLoadedContent,#colorbox{box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box}#cboxTitle .modals_description{font-size:.7em;font-weight:400}#cboxCurrent,#cboxTitle{bottom:-25px;font-weight:700;color:#7C7C7C;position:absolute}.modal_link_hidden{display:none!important}#cboxTopLeft{width:14px;height:14px;background:url(../images/colorbox5/controls.png) no-repeat}#cboxTopCenter{height:14px;background:url(../images/colorbox5/border.png) top left repeat-x}#cboxTopRight{width:14px;height:14px;background:url(../images/colorbox5/controls.png) -36px 0 no-repeat}#cboxBottomLeft{width:14px;height:43px;background:url(../images/colorbox5/controls.png) 0 -32px no-repeat}#cboxBottomCenter{height:43px;background:url(../images/colorbox5/border.png) bottom left repeat-x}#cboxBottomRight{width:14px;height:43px;background:url(../images/colorbox5/controls.png) -36px -32px no-repeat}#cboxMiddleLeft{width:14px;background:url(../images/colorbox5/controls.png) -175px 0 repeat-y}#cboxMiddleRight{width:14px;background:url(../images/colorbox5/controls.png) -211px 0 repeat-y}.cboxIframe{background:#fff}#cboxError{padding:50px;border:1px solid #ccc}#cboxLoadedContent{overflow:auto;-webkit-overflow-scrolling:touch;margin-bottom:5px}#cboxLoadingOverlay{background:url(../images/colorbox5/loading_background.png) center center no-repeat}#cboxLoadingGraphic{background:url(../images/colorbox5/loading.gif) center center no-repeat}#cboxTitle{left:0;text-align:center;width:100%;background:#e9e8e8}#cboxCurrent{left:58px}#cboxClose,#cboxNext,#cboxPrevious,#cboxSlideshow{cursor:pointer;border:0;padding:0;margin:0;overflow:visible;position:absolute;bottom:-29px;background:url(../images/colorbox5/controls.png) no-repeat;width:23px;height:23px;text-indent:-9999px}#cboxPrevious{left:0;background-position:-51px -25px}#cboxPrevious:hover{background-position:-51px 0}#cboxNext{left:27px;background-position:-75px -25px}#cboxNext:hover{background-position:-75px 0}#cboxClose{right:0;background-position:-100px -25px}#cboxClose:hover{background-position:-100px 0}.cboxSlideshow_on #cboxSlideshow{background-position:-125px 0;right:27px}.cboxSlideshow_on #cboxSlideshow:hover{background-position:-150px 0}.cboxSlideshow_off #cboxSlideshow{background-position:-150px -25px;right:27px}.cboxSlideshow_off #cboxSlideshow:hover{background-position:-125px 0} \ No newline at end of file diff --git a/deployed/regularlabs/media/modals/css/index.html b/deployed/regularlabs/media/modals/css/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/regularlabs/media/modals/css/index.html @@ -0,0 +1 @@ + diff --git a/deployed/regularlabs/media/modals/images/bootstrap/controls.png b/deployed/regularlabs/media/modals/images/bootstrap/controls.png new file mode 100644 index 0000000000000000000000000000000000000000..6fd3a8e13dd306de5d9bea6a2717b53d1d750a68 GIT binary patch literal 586 zcmeAS@N?(olHy`uVBq!ia0vp^1wbso!3-pSp5j&pQu70RLR_V!q%K{$l$x6Q|NnnU zNl8~%*Ug(Z1KAQ165`_GW@ctUHV~MYm^eE-dwYB9>FEKLb$53I1!ZJpfb410rUA)< zf`VDIW`Wg$2%w0Umlu!(0w5P?6wo3dF(9^{+q~g}yE6=kI8;GzzC^`Q|RzLD_SnlK- z)87BKk5=uT72xTzG$2F&#rdxfYaWcX3x5f=hxh`oFFw;=w< zrrg`J9#>3FYB2~+wcU{y!Vz-z)=kBIrq}1`D3v`w?IR$X%vJb_Q}4TJo5Py#-u{Ju zy_RoWz@VGO-@?jWb!FwY*_Y?sRd_T}%x~j5ixd^UCvGNk+aEY3+WW128@FS@yet9s zQy(uJX;02PC_0BZ@hR))Zi@*9sgJq@xtA%qADN!#S6r6d<@$;-G3=AYg$f3@EeoDJ zWjn0Tn^$wRV&<9T_*oObwOn{~qN%DZnxk>U-O8@~y!DUlyN%cn?rhle#<4cqd4b2> zyN}=eJQsPZ{erB!&yFcJ7vuQ7-d$x9pZDzl-{*f9|77^JLwdbP0 Hl+XkK&DsEm literal 0 HcmV?d00001 diff --git a/deployed/regularlabs/media/modals/images/bootstrap/index.html b/deployed/regularlabs/media/modals/images/bootstrap/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/regularlabs/media/modals/images/bootstrap/index.html @@ -0,0 +1 @@ + diff --git a/deployed/regularlabs/media/modals/images/bootstrap/loading.gif b/deployed/regularlabs/media/modals/images/bootstrap/loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..041f7e2305d21cd901dd9547f54a519d989c5525 GIT binary patch literal 2608 zcmdVcdr(tX9tZGC9yiG~=H_*Q-0%n(lu>!CRf^T^KyG+t1%gl;HrORx5&~9@G$@$u z8blEgT1ucOw2ty<0mT)tLR1O?L{O|eqK1OOXrhh-)^*zs=@CLpEfW^hdu&}VXxw*S{?~aU&^!4=_jYhlOK0G|!(b4hb z$rGE+*3;9|+1c6O-*2&4=I7_TySuGc>+I~TTCGk=Nzv(aEjaU~LOmuM`{%T_A1%5=fLOs!g= z$Wr9KyIYYSn7K=}8}L~m(IDrpwM$o8LIA+UFuf+4OQ({F`ZSZ!YoJM+8zwyac9`;# zBlOM0=7aix9mbT>Rhv_Suc_9f1F1yxS=T3gCFyvLPaWOzejpHNhAEUQLj`$C;eyyd|wi}<#VXd^|a?IYRNYm zQ*g#z+MsB;x|gHe_u!Ic=C3Nihn@iK%$2|5VL~uN4j_oYOPrSO1j=Hwa;vJ`y+xG# zOl@X;Jwvoj&f;h>FV9xQ10bkQe1U;R1SaBt?#1}1F$0H(#XO@s8E+W_+>EXuUN(8z z$hA#c<@Y9;_?9~k2#>w#fbqDijtY7Fmy>LjG)-~5>RnM&05z_$rE0L$&8NnyeZhs8 zF204<)P#W{mhgR)m&zHZjJg{P=*aOj3PZA1XFj)w7RBfV&C1i?LOaIHN1! zBY6}K_lRLU8gCec@EE*wP{hO~6BFQ=>`H-Da$=)v_xV-b2Kl*lppXPibG^ zoju@FoWnB?-SAu7A=^!Z92J1{*Y zkL#W`$>J|eT*Rdc8)ax>KKwXYcK_TSs z_RcA8BODgP!_v6lUSW6uzF6VO{)g$3Qh|FH^Z-;!=!<`Pi-*6qf&x>#yLjPshYphI zw36nZ`(Q?(^GC1;43-V-Hz}c4aw8yP`Q}ks(S&$S<0j;h~gS`m}G; zsfeAC<^GEM!s%+ke|7q!FxVCPS8ylI@6oK5treIYzKn@xiXmY4rR@iOH>c~J?O)TD zN)$cox;#YWPjGSFF24$1MZ04AVnGMd2O{=Xl zHuaX<_DOYY_UOz+=Ae3L=KA*dp0WPylOv+UHL}2smw|?g2Q9bOY-|HU@k#+9IH3Xb z3*8`QT?u4(`9BM39`_48UiY`Lp>k$Dra-&aI@;k{@=FmR%3B V@82+W!C7&eoE5ie>3{TU{S)_ktzG~C literal 0 HcmV?d00001 diff --git a/deployed/regularlabs/media/modals/images/colorbox1/border.png b/deployed/regularlabs/media/modals/images/colorbox1/border.png new file mode 100644 index 0000000000000000000000000000000000000000..f463a10d838aeba263ff44e5c3578dfe7ba07648 GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^j6iI}$P6Txn<}3KQfvV}A+A9B|Ns9>Z_d99WHFWm z`2{zujf-{zawI%m978JNrXFPE1@f8<7E8}%%lTu>&#KnM&G`7uteHSj22WQ%mvv4F FO#q`M9f1G< literal 0 HcmV?d00001 diff --git a/deployed/regularlabs/media/modals/images/colorbox1/controls.png b/deployed/regularlabs/media/modals/images/colorbox1/controls.png new file mode 100644 index 0000000000000000000000000000000000000000..dcfd6fb9f178454613123d018bf742c8cc905df7 GIT binary patch literal 2893 zcmV-T3$pZyP)_ZK9@9A5hhZ`zJ|^XJp&7A=Y=V7G`@Q^Xk=19M@a5{n88C2urGbw3uPN`H$U$)~*R zDGEm-Oe{b=fr%W&zPaoidK{8ZW&+R7$+5&?)ea32b3ErF@rofuL&nCyXl{)NO9?c& z5Ey{Uhey?FhDDCD(o(}6HC#(hR;g)@MC`aP{9?V42DhOydhL#M>}EP`9b!c^x2QOy zl`aYl$KiM$b82xQ48Xo-M;Wj`j>GZsIBd4V@8W?T$FAK`0i&1By^!d25J#Rod6E@u zbDTbNhJA*=q6g#0^7E;26cm-{cE&DUxDwEt*rWuKM!V(XG0kMn79Al8g`GaY*U zPcb))2!6aChtduaM~@zruKld;HR#w;N$y8w#t9g`ZwxUhn{_m)8#Zoa+qZAurc>{> z(wWnz+5gLzFK0#B%%h1{8*kO(fMDSfd4Xua^~Rw?s-Dsc2Nz>g(;?>JBav_nr;-X=cl`B@5o*7f)K+_H}g~MT0F|A*}o;F6q7%Lo@B8CTVXt+NF zIygA!sVh@M2)>X;L@*enBS#Li?QPq(QDb8x6IxweT}-pfk2lMK=KJZVpOOE+aN*y~ zGv?*xO$#5aa#U4SQ6LbIMO<218pEla=rF=z71DM1q~e#Z$y6*V)x$OE`dg$D@&v2^ zdhTetF+m_!JiO!Hy?fdAvSrJdC!8aB-QP-|L1gIBZ{4~zrsDZDv{4R-3xz`pO<7#J zYuB!6okXh~oTsLyhW1OX2g0G}pZ|gG4WPx52#y^)=9hj$OT$h*t#8A)SlTUBr$r=0T_cSXuSO zy)~b`5h~IUv47?7;DQ92Nwe^eJ3B>q-9K00<@A>-MNu32V zYQo~n9rcb;au{u<6XCGK4lD6%vg^x^bGm*Mf-h4-Yv35N%EONNn4i9N4U=f*8;hu1v z!A$Qb@Zbs9gNKJXgb>F@mEe!WC)#UwBC&}Rc6dl50V@-Nh>1tUju77`8A(Sl9;}vh zq_?-1m1J<(VTXq_6EHj?1Y;&42n0}GUT)Y^8cm*pXYxc2Gm{KX*x@0~1k5YlY(fw; z&o~ZitC1OD2m$&lBr$SQJ~Rxw$!MDV=bxbbqucEfSkNx%x5c{NDg8M_bM_ zvA%QaGM)dphkfRoQ$X`eAH>+jL!YkjKU8{yDOY=WDww&5LW zeZN!p8uU1<0#8sRL&P|T_ehZfJgum5inXGAE^YY63Oau3BI~KwH=UwShCgH9%`JX} zzUyB-ty832@2lj%NPq}^} z+|#`2ol*MrtIc%c+<$5JPoFi+p=Jke60{%?DhF;5*wKAU>hukKN*!9pZB1{_VO!7rad%iH0g+loSbYbo}EwSWks~=@dZ?vpDTa2_AATi zwb~bAyuDctggHOo=BK3V@fH>-b`M4)f=plRGzkVQls9y%Y#XRBepKX#q>*)(oPyd6V zrg(`>)HsxwU06V`{A9DLcoXILj(;^B+4tiZFK?3L8o3{i*pQOMCN?DmiQxeBR(&BX z(V9U^R$>#}bXuLzIEhX07r(Dt)2t$VsEg_(vl5$N6;?75g5W$_Fp@k)OT0#trx>wA zOS}f{Xd(B)v1@mH6apSge6b+STVQA{0V;iPpifQ+qPL36iKHVA*byXmzNyI2JCt23 zU_hA=1VX{oubKc*;gLJT2_-ghB6*5Uc3>jHZ7(`>bn+ynubSoSX?f2c!orING0TOC z0*tjn82m9HD~rIzcowiD=}408@Lo0R76GdXKr7yK!^^(;YiG5f^Lkl50do diff --git a/deployed/regularlabs/media/modals/images/colorbox1/loading.gif b/deployed/regularlabs/media/modals/images/colorbox1/loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..b4695d811d4f84ed693eff7b5e6b4d61a3e8c48d GIT binary patch literal 9427 zcmb{2c~}$o+BfjYkbx{fLNXyN2~I-9fRL~W0YSqMAPQmvXc3WJ1&c@(6VN-G66{!m#Dz&KKu^y_lMYNSx+iL6S@to6V&NF~*-@fnlUXMN3lYjN{kB{H` zJHPuk6Sp8%7M6_w2=Fri{G0eK0q}qQ6Mu9M|N1`u%P;s)H-1oqA2;E5d+=93<3CK` z#|(Jq2l(X{{QIx*J;k^=2|tA4&mQAH|A_D3iubhP14r@F5d6Jx{6jh3yas$&IP=`6My*}-(7^Ct;HXY;7`Z#qk24xg=aGHLJ^+fh;NYKA2s3Mj^Ptu z;6FaYZyd)j?8Ljal__{%2i~$Cx1{2A8TgJoyfz)LUW&gh#MdBr zz6W0HgFm=||Fs`)%Exb=#T!=P>wWQS2k|@?ygmzG&BNPD@b*pkCnxbDFZ^&h{=q!_ zWF?+%5B%{b_%}Tk z)ktHy2%RxlI5%?6ZY$l%)y35jfZdMF$LOJQuo`5!xq7<<0wEFe!~iNDmRQ*CZa)6) z0GWrehsCg!=jkR4(xXzbtX4ETpjXdtu+U&WRP|3YXlu_B)iZZ=0#*{4B6KTmiGmnj zsbV4N=yD-QamiN_E; zVH?&r%TH4=`CvaO@re)|&d6egk9{2n%lVPd7of}(SV4M46aL@?LE0h(9W?Jl_KBI@ z-F~7hZ1jBTPv3t2$>t>FO^_-WY)duQCv|z9ndY=~Svu6Hr3d(F`3bw!v{nFdSgB1Q6VHd-c*2v7ZF{IUDRuWvJx*p|Z5ICc0 zU9HLoXRA#bkw5at2*g0eOp5TG8Vz>Xt$RXaKySuDSWD^f5vK87d0?b!)&Y(Lklp>S zy#DM5<`3iSo(CJ-I@{Z&N{aBfpEr;fm66DjO4mp=mt$?+3QEF$}ybSEVM3Iy1aWU;v3!lv8_ z(94N*wM%9t-?HD>a)R0~i6wDstS54=)@v(hfU8`dA#{$G9B$~1a-x=s!+qXe-}adL zfw5czHyZi?SlZ<6qtVKl=Ag{T4Z}~F(9YXfkNsPQ@_9(Jvt}nU(1P%gG6{=T*D_4H zn9}F@?Z8zHS44KwRKPu$dlVUtDAhh|DGz6p5;U_!Mg36vcSM{Bsf%UAQ2x(jrxz`8 zB%COz^WwIdX}PIID+nhjG)fESrRFcBwPUk0naeSL`XQ$_fWfywA(`&(g#Z$JC>EkQ z6gkN(T#wAR*ZKjDt}g2UWm;r$vPClAgPG$9Kz;?-+Q^l0!Q1GHuV(4vQWdwGVL<_8 zPX&a>l1QX#Fc5r!U4>x^n*#)DfSEC}dpgxAxf2ye!hD+mRtG%>U1&-X0oSYC+0K*m zHxSc!jMY7{(a^UjGfH(qw#?8^hvgyflU+}xDtI$L3>12&>>hT%nACJwk=+BZFp4ID zmQ{AZU?I0$4A`EMh^8=g7a~)#NW;@(_tv^M8aqAe9L={>Db>Ol0_knF>pMtuIYQI& zbKG3B_O$~HMdBK4mzz&+8$g$Aqf+b~r~txrbMXXdEboOp%i<7w2M;k2q*6x%OV%$7 zpKsxF6T>`a15nap%=3$I?l#GzFkgL0@!V{Th>gba_z#GoM|{jJ4)N-#ZU<&1XBmSCl1mtY_wwt8L-wWD7pAUqKed7V8ni;XY6EJobQXbvd z6@TvgPWc-pNHV*SW~rL#loGVfjCeUM@&ucW{0)0@5Dbwrwk<9cW3&<{)!S|K%p!GC zH9KRzvH$=boEDS-w9J*O*C$?@?HrRx1~z6n6$0}&-CDY_8cAN~7_uCIq$j}GRqKmm zVGF!w-OP)+xaYB=W+V#ZwLQOvS=Ci?m3YWNCV@mc@`o{bMGUOUS42fS8LN2yMUOj` z6lE-69TTs?ymO8-#T0~ zQDyd;Lwlc$^#C6Nl>A^?R<8q+FngF>ocpZh%p91MFjVS)v=tPcy+7Sa?-NhJHyJg^ z#>P@z=(#qq-i+9<&9#G?jI_@a%o{^8UvT87{IPi|D{P7@X##&WXU#HrM6hciM%{o1H zt*XLA8$$p^S#Ps})Rj@qOW@5G$E@?en5q8{5g`Gh-n?9Jj-fq<6ksF?Zky2=@x%o&X) za6X4=UkiZLLZW`qU<_2W+ts3*)viiQ)M9}QfE+n<;vgif)Wj{gOq1U~`Ed z5Y*+J>S&RRlLVm{y8$Y3_4dy^RE_Y)>3W6tJSN(BY0qOb&Ca7;y{cgwMoMS73+3Rlc2M$#Yn%LG zav37dp!h04w|xsl=-EmUC2nB1#Upj=i-QwYOHkBN7dK`*2O#@;ETML2ZbyaoI|jyY z7$TeP7!RC%t1))tHl&_JKQ$P;}FL2m^fs`BwgR0OTse zLO?(g=d@_1g)Ox~0cfLga~G1BqDo+%tb{_vVkrzr=ToFW^om6ZZb26LEinTVjYF*a zrJPQ}=e9(jkx=UK+zLsC_59@!UwpL1JTtoo5@MzwF`C7(6c8kCnU3Eo)afkBvuOT!DJsD{rvo!J<}{! zgNR;J$%_sO-DdLTI!0?j=^C09K`?07%oz|6tXP{n!y+PRumY}v3xG3Y(^ohgt>R6| z$TvFk0Nax*;xARpJ|uJ? z&vvr9xuuByQG45}A>DU#>(1RTw9F1ySJV>eSj=r%R{^!Rq}VO34CCAXbEk2`%@=M{g(h! zX{#8*+-1NxuSEL{IrC4pm*{EuDFRCQbZXEtFTJr70@hTbi+x4gOyq(JQ;vydoka3v`ibJezt624W}n(xkYxBFro!xj+t-ADrpv^ zU;03|-2I)9Cl*LDphtXXy&#b2a{12&luT~&9`~`(Z1X`iYcAhCGdB0q%5pgHAau^ZUy-{8F?>{UJ)>(^&{meh#`Qh=j9Iv+D>?~ z?vWE&^|mGtegG0FUgZcF(?WDEJ?#|~5z})HX~2NN8Ys}GzNF${!?FwsY_~|fX?79O z+?B7JyBU0=<|YCK)l|WuWLmw60N|A)bylbiAn%f5G^&EzSREWnDD6+O0ieLRFgvj& zsuKoK8?gjPBA)yXd#Yu-#B>ZfwsFuaV{aw0Q+h?W#;(MXUjs=V>X5~PCrxHhB$GWg zNXTTiS#Fn`*DdeaHjy&R%~b7g>{Ds&VrP@Avz7$KCwxNL$af!JH-tj%#)IxH>7rI$j*GvS_I4pw>Czy}#N+hil4dR;%&s zkq76B$&W&4n=*DAcLL0uM*Ksl(B zZJa?JBHHJHUKaImj{yo6i3W^QCUk|JhnG@rIw1~*-yb=?uPRD}Z-){dXAL&^JFXSi zZf@T#WW`a=>S9kRWKKay>^@%S=5o_p-;CU0` z(hlF{a+dVcagwIo&N4eSF#?Plv!$krBdp#nWATmqGlWJ~i49b91jsM#Y0K-GwSo&9 zG~>m8OD3`Cu^)_1t!&me9Wo+8Ae#|%EHFV@eFPmfpZpBS$x81`>42=Y4& zLuwOjC155CClo&4Oay332E>}0r)e(g(B@vEXzu9YQ@hO|0##1Zd?{T+^&K=G7JqIC z-5AZ~&NBb-q9Vx|ceZs_j}<@K+2&}w>Vol|kCzKb<4xy#RvPs7bM_(}3V2f|kmlY` z8NNrrYyfuyBw#$AEP3akxHN@+-z%Kv_B$;tt#`RAxLM!W;5AaLxz|ec4)o~8wm;FxkO-|aF@BeUCS`U2laXOa zL;2PwvGmj=41hL^8NbS~FCVOicxNx@rf$xr4uM2ypuJNtW=L*hBOfpkGDgN?zk-5$ z-(P-Vhzi65kHUn^m7PMSU*b+H*w-v5wjRHE|JwM1D~2eQlA1jMk{L6+!q=bpW`LI~ zP`S(<+Go3q!F4ZqS9_HX%$oPy1@IRoHal%#MSw3*dm9p5J5rY2m%7b={)cjw%HGa- z?!5a*`&hrS*`>j`v*+LvD^?ZYsaEA&zsaxAF(qTIwYEjAcA{s*DQJi4jW+w&b0wKV z5>3w)IE6GlR}336GKutCeCPyHFVKMzM#Ny9CBid#yEr*me8OmN)znx)@{c|xhHBJ! z%{&v`5Vv_oM#j^J|4#DyEB2yszCpgt699{LfCFq+9+(>7akW zfogy29EJ@K{N1LjS$x1kzeGI8I{@~j3k1%YPs)GA(M{r9|203|{pLdiPG9rcZ!djk zKrg*8P2<}Q%Q9_NuyG*N6qcj1@8`cXN$|VoB~$(!IRN;JHr5S#Cbu!zKS&? zO&-|l8Q;hO48g8fK#dzY#IUvWd8bYfCz4BC*ei`}0Qz=J1d?m5CFpiV>v|1r@SAV1 z>4E2%YH426l;ZP>MVM zdc@t)Zq{Rt@Ez|v^-lZa8zNjk z8fHHFG`1IwyWl2s{|+PVE3_r3YtL~brj=jJ5)QV-EP zXKrX;$L2P11HHTQHaiQ`Dx>Hg&E8ziMU~pawp^DvJt64mU=Z3k0+c_qLwM z+HSQuv&P}RV;iE?0mPl+*A8!fDEwa(Iv>g=dbxXt3C&tKhZSlPT_T%B-jR`WXH2}P z7|cWaasZ9}dymQ2 zl;Vv*VU21pCk}3ND;uj7M#FZH+&_Qpad`{%jz>g}HA-7&fJMOr>|`cnsuB;#T6@0T zWlPcfi^xL8h+i(%RW>GComR)Q>%6!ten-)tsN_GSXE#8LdVSClk>$|urE{)X{E>xz zktm%L0Q=%)B0Z=7ke(W}v+7#qY#0BxcNro1`3EM{W$q8_OrnbfkL$8!#X-+5wwa@w z3=P^NDiV*3!4VxjP?uWoG3XDBGj%$1@o6X0SD1ixCo7T#k{E2CC21=_Krzzpe{kmkwR&F8%4=f1IBGTu3r06fJb|oD{MlkLc0TrNzZu z!l=!Js#mRAx$f1^l{qB~#>@CK2_cu@4vj4#%UTge6_49x81p58@NS~^o zFy`s$2oVJ&S7k09oNgeQ`uJxp`N3)WraKOW@eO-bD{wsMg~T<8^F+cD&^(tH)*whkvv9hJGh7 z=QK`|*)AxnCwBaf)`KUQ)>%>q#o4{qGe;)3b)P?TX#Q=)w0vS$Z|3a=3Kq?uUbKiQ zYqe~M^tPQo_k7eWzHDL5jf`br;AwX6m1^07xhoe>zgU&cFFZ{=-Yrn@cChM8qp$m- zgaw(?S?V?*v8n&^_g9)k*u}nc0&SGm5vEdY6>76X-autGlc6T@PRe~jfx;k5Hl~Y8 zYm1n=)fT0!al?L{fHmSauT7=9RTe=dmkm*XxZ{?pkp`J&?79QsZ#R+FRnY4xv~xk; zp|)%rg#K0Nj3f(9z@&&Q%TI2l=2azCy>;QN9aWR6Egrt%taf&Ru#+oIE7X%FNyGe2XiOJ~^(EEihIMOWvOkrM&PH^?tlG>3DJ#_1HXGXkfHV969wl3h;rJ7JHeh-gNTvtor)e7uAp zvNv3so6GXzwJDWRF*Ys@{=+@J5eley06d`tAUA%3_qWgc#sst>54GW;?xsz&=w##8 zlJV$W-VXrH7zMa~Do(WYZrF>w^g)trpS`$U$iOT7D!w>xrT`cKdxqE`{ze+F!n`&Jt)3a9XdSEd0L4vg9{RkWc?l< zG5=(g#%*9S6MvXAqKK6u%6Y)1rLQbJY*?0v6!pqj5Ifv|HG!&uQ0sd{ESGC38K|uC|6Kk zGB-S~5wx57+M{%Cq*r5bx~sR(UU{crc4h8@qAkJEl10~!7q>s;6wwG+ x;Lym#%7w)E5SqaM?W?}pgPY2~zL+0j{rLCv$(}1!-+=Zpc)I$ztaD0e0s!7!I-dXl literal 0 HcmV?d00001 diff --git a/deployed/regularlabs/media/modals/images/colorbox1/overlay.png b/deployed/regularlabs/media/modals/images/colorbox1/overlay.png new file mode 100644 index 0000000000000000000000000000000000000000..53ea98f7003cf014cda2f764a7d982e405bd1b5f GIT binary patch literal 182 zcmeAS@N?(olHy`uVBq!ia0vp^av;pY3?xs=ZJr3E3<7*YT>t<7&(6-y!NDOSA|fs> z4iv@@^0LaF09818x;TbZ%z1NeAuof1z|jlq0?ZV)A8h5lQLnD@Q>uGq<+3e(rH8NF wGFLG_IXT618W25kEc*C=-akH|?*IRp8MKNmPAJ`FsRUW)>FVdQ&MBb@0FX~HaR2}S literal 0 HcmV?d00001 diff --git a/deployed/regularlabs/media/modals/images/colorbox2/controls.png b/deployed/regularlabs/media/modals/images/colorbox2/controls.png new file mode 100644 index 0000000000000000000000000000000000000000..8569b57f1023685883cc8b2002f0763d4e79638d GIT binary patch literal 570 zcmV-A0>%A_P)P)t-szrVkq zpP%pV@Bjb*hlhs`4-Y>-KYxFJ-{0SWfPer10MF0QmzS5fx3_O^Z?CVf=jZ45_xCR^ zFQ=!ckB^VX$H!k^U)R^yPft$(vqlU600F8=L_t(|UhUP{YV0r!08lO7oqd+}|G)Hl z!i3VX%tTOnA8I`$U=bY@A_e$=M%TN3lY!f+1HvLxga~{?BuQU~CFD&cP&}kihULVfuoZsnL`Q~xuv-(kN1b~-H0OM{*xPj(Z zH!CNOhW5k_q@1|SN}boap^M|QnCG?;dN+Z!dVAB#n~UhURSK~f1n|Kh0M!3+UH|Rq zde^(&^{WhANm(+>RB+Do)wv+)v?Uoxo50g%A4s-!(kB#kNXfBF2?Rac)Y4OdYNDL( z4|yRqDRnG(a?X8zNABgQB&u$9*W%-n1wDO|M)&E6m%fjfBtF&nQELn5^(nRVcYJ19 zPd1#^{m<*$d7bf{j>wU@?OCGtb_Kzxa>qde^)D4;WrrV64tv9smFU07*qo IM6N<$f+}YfD*ylh literal 0 HcmV?d00001 diff --git a/deployed/regularlabs/media/modals/images/colorbox2/index.html b/deployed/regularlabs/media/modals/images/colorbox2/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/regularlabs/media/modals/images/colorbox2/index.html @@ -0,0 +1 @@ + diff --git a/deployed/regularlabs/media/modals/images/colorbox2/loading.gif b/deployed/regularlabs/media/modals/images/colorbox2/loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..19c67bbd0403f3f00d71bfb21a59cb6c55d482ab GIT binary patch literal 9427 zcmciIYgkiPzCZAtoosT0Tz3eU1b0G!fDrBw5Htw^q97)Kiiq4%u!yLj*s-0kLm&y4 z1Q6vW<)-2tyh{}UQPHA;Z7o&WBHAgf?Nq0o8RyKLp8p2a{^yOIIrBUxFL=R|hZi4y zzwcVVwN~`*?u9qtRSk zTrOO=AeYNSLqlU@W38>NwOVa@db&U$u(Pw^la^y#OcUb=KCDJjXp z!GXu)F&K=<$jG&8*QTVTm`tXutgO`3)UK|swzjtB=H`P354N|rXJlk}czASlbR0f> zSS%I?1_rjawk9Vh-@bi&U|`_fxpQ~#-W?wwU%GT@ZEfxT{rlBw^`1R@>g(%kYHEx| zqs3xrXlS^0?b`M0*KgjudHM2XiA3V>@2}VEWinYsMMZyq|B4kW#>U2~s;X|?y7lh6 z@9y5cJ0c=taBwg`KmX{_qd7S_pMCb(Jo&Fb1iv^$Y|qIk%E?A{38Jjao^0#JW zOY#afZUqE?BLEQgWx@YY<02CiBIN2wKZy?>hyBWP?r+Tf69MA?XaQ7LrZ2BB7)_N` z)iq{IZCx2PBq*RBrE>*3C@^#htBJy}6WXG%a7lPzn}y1>x3i}Ku)~REC^c9H)_^Pr zdv`lOASi697*L2OBxbgwgNIKSK;WV52{CNpIXejb%N5>YX`N`X?@&3v(M*B)Q1yRR zf>zcn(O$;>9>9Vlkc19}?Q)3jnj{wDPOcY%B)eSYxPo~$*OtjqO%D!Nuo0LuC`Sy# zN($UP_Q}0Sq7qIG^%%rmugue{j^kP1u0KmgWn&|_xNn5uL~1%Kbovj`u#6x6e7S;= z2rF?fDZ(F_5Tq+mQo+hY$RRPKzu!xgj!s=F`RThaKH3$JymG_64XJ|8HrH@HlGfK( zQkZMjr9e$Os;`%hAA3MU=>QO$`*;AUt`jWe2^zbAQCEMkc8W6wdiq&{#mU- zaVHu=+e;=+FpTfY{KD04M>rBd`pJK1k7PWm{Cza>d4RFAr>o0bMH2RUxdYkq)Hs%O z_QrWc$0;mdQK3-XEvH`o@{5lyocijjmI#5bq`5OtIj;IIT|wzW z7pF1Sqx_U(%uayLH$y>bj*j^N5_K#JqSzELrDm>E+B;jk0GhqsRzQ^;UYKB(EOTOH z(g4US58V=;6CKb%RetSO9-XAT*8&UjAZs!pJQa__)qsBB3-me+lh_=#EUWso$uFMz&SSU#wOGz(1VlWfhulVjuj8h~s^q0dE({U3EZMSyo z>$W4j6-i+m!8cc{G{Q&>=^c&zHl(Etq3HOT4)*DXx&XQ|ZZmqo!6T~^ph_CZB%%!& zKo|~o&H#nwzJh076=ZGWBnJG|nh0R^_I07l%zSQKh|^*KieH5~e;LYckUR z$0>6Uf<)+x(NM8x44~35!q)cy#-4oAliLSkF8r}a_Ns!Qx8g_^=TpqpF3d##hDyYh zxzZVIG4gkOkcps(H@#t1z8IwxG1c#MQqu}F@ipw!WvV;?v|%nU0w`%Yo3_UdEVhk| zBLKze%zR+k&bw=hYmkJkw4n6>wJC#wP>nk zYVo*%fCI7W$eloC6_KzyS1FHR8moCe1y6faBvll>V9Ls6WcZ!{`k2ZS9?63}HK)}tYwi>70JrlLF)s?P+l=leeAn<#Dlp8=vAF@GW7f%oh zv%YUX7YO5G$4h)pc7USu4;M1&J#1}TXf><1LP2=ExhCIvi{IW##Cl5>5o$J4cD1Ep zPJR)vStO<(IgnBW0wO2(g6JB`W?ybS7`-Kh1yDFXxjVDYSMdeM{H1`Ob5s+}eJpI5 zndfP>SO7r5^^kMH&K$=RH3-3TJ+C}+ZO%KQW=KS>5U0GHRwOzzq%VDia_wMQBzti3 zR(g6Z$`$+FSC>5<<1E^ut{(2uFmXZTq^b0?(>JOsOq6K^P?iq07$_I9@CL(H%!Rk6 zmqD(Q1zfpJVvqRq>^1+${~38wSslIgIm|kj8wLi$tkFhT7K7Z=()#5))#6r^>6#6L zTo(CM@!Se`;nbUQBEC(j0s+l6^2lYf`l>~ov_(xOa2bbTT?c^Vd@Ozx0Vt^KBGxH( zY3x;I`6_`FfM}e+Xb1@@@o>*PR0(>Ey%I!#U{{eB;D6CQiDs6G;|0MeyAdj~clSv< zR)g?nsO3ucr3^*WiBskL;>9U@HWM<@rBMnJqp>$vVHfO>?Fr&+Ak+JXKg~`yDoceX zTW^oh`(4>=My2i4#Ub?so}SoKW=A@@t_zfWY2PV(oKT90Q%Rmm(BaT>k>Y%nh!j2A zW_C*2^Wx}i^=gHJrjMSs3IqtAPOHh?+I#Zg5t?7jj&VXIk^acmLza1L>chExKxHuF zRV9($W@NThQ1S$n+R6l#wcmat6w$m4LP1YIzJ)xrJXcprZixh~w13|}TFzU%X0KKaZ|f8~u2XDI$$lQCh@_7g zlK#Y)?f~JvA;TB$GNAYVieC0t&Oj8TR;67+R@l=DrHiQ%{DT`zo?Kdl z4)oqku^0{! z0z_zB)`rB8gEh#gcR)Ee`{^?bW~`jzw*GmG38c#vH;iQr#3zGkad1c!{jKhvMT>jr z;Lx9SSZH4C$Kq%kV>1PWjf&>JELklT45oOz+bf{3UE>I|{)z3nJJEj%MKXPrn=T`_ zu|%q!j&bZbclHQDz?KEM)6}weEwOxHeQ*(FV&5|+Y42A6LuI8LM;)cW46jJ{J#y~9 z*sh{yp=U5C)wB6VOB;COMEMOT1gx!6tnw5!mSb1V z2P@D6>k|NIu`A;pnt8!U;bp}JHgg6u*PEr+F(XOm9cRePf0s zqveRF+Y1bdDwF-ipdb*M-Di9%RiL#UvvmjY?k-HfC4X;0P)z$ zZ}UNo^njR(BBzSSTvHELA+6rm^qYxAG=424d8|iP3BGBr1VvKmGlPUcU{}hBS=s%v z!G_sHHwROVk8xP7BSuPCL@@!ry(0gi&@UCvJ-!-a_A;g7NC3I@{RaeP#_EuPvikEXMOE9$hFTJPD!@ zUcuP>3oud)M*9E3=tMmDR~MP5mB7M&#d1_6@GH)5tf9YB;a&H?Xa+Hqqk3uaBJwzv zK99n-mP!v;Ix8;e_FOMx zc@OmBv}Hu|;-t7RP(E!%P7;S%+}o#PnhvK5jjSR(RC@x*Eg9_09(3Elg$>%7!apbA zSk$QZr{+gC%bO;n{U#L1rb6>j)FxfyTmk7|NiCm%l}{H|K5T5(dcy=?ZuRoEP+JdR zm2+C`wOM9?Frz`e!Ye`CfrZb5a>f1+Di8Cg4D&#W#gTDAi%u9%i33c&L>msrX+8YK zNBd`o_v?sR;`m)%2ZREpXzJ1vfD@uX{C4i>`^Zws$q(I0RooE@9PI-Fd_Fgf_*Sf1 z;XaK`P_ku|l9pB2|@d?8thohhSCo2yHHIVrcQXONc0 z|KsJ)Go~8hp~qqwb4Lm;pzDNS_+S#K-=eK zy!V^wE#3#`+e*=L!a}`z005CwSC5+KST5@autN|?GF}b`v{g~yo0an@{Dj4e7ROf} z7e6w3u8vfxmOcOA>dT4*>tC#cQpBuXT~mX>s(ePq%@Y;?0{2}K=NO`_?I}VIX(l$k zW6??>GI`T5a%wx6d=V5x;bD*6;-I5n=dY)QBv}K6h$4dJvDm2;DSX0$IHA*a?tnsZ zPvlCG)lsyBs_u;L{^y9$1g+Xq_luo!2#8w6uK9=M^WKH_ih9#tjDHP={RRd>eubfX z;{z-h%v|6E!POlV8Yhi&KCnhGwXv8VW>$=h`1j# zlRMRM|Lf|*%rzx@?LHCQ+1u3UI$5ZF(1GO+^yGHKn?z>*3o?p&6a7~iXijE7Fjq2k z?_j>AS?qmg4hB%Pi0Q9o*jJC%K)myp_46lZ^P51dXrP1hFqM!DkC%;_Fc~9#l~-Qg zgFjwXN@}Z<{f^8o*|j;sIw~QAd0@nc0v2quP1xfzkno} zM-nac6*!Ny&{uRk0hvR3Q$AD-X$a^>F(a(8&SS+hce*&&SbWUrVD)@kL9!1&#hPl$ zc_BT8&XSo^~R)caht5PLi@cUAU&OSE6mI3;H_y_vz8VUKYb}{>?0nXH7OIm zkTJ-v?#eyxpAMnMCGkGt)yYp-4juMy z<0$?K2daCMIdnV^{MF`Si};9{I)JU?-2i*wGKO>Rqq5gH`Z=7Nuj{9Or1BVsGu(3i zyMZ4Jih&oV1so|s3OtKqsL1xGDP$7*q@|0z{M}La3~`x`lgA1@dOCvG8Uhf)E(vnW zt67VZWquvbF-;u65MX}|)H)D?40}qR_vp*vI6{#fJIBZdpzo$dAfe7uq}ZqI*sg^Q zUdybtgK(g!j`CH(?oRoQXM9xu$C4AeeGDVLm~{T1ap3;|hZ-#ZU*a5ig@ZqBdN!|9 z`AUaW*z?&5M;g)XDMz@?{XW5ET}hHpQG`_`@|6R>)cJ5M1VE{0!NSbz``n%RyDeEa z?l6GVi=UK$GLxQ@|B1HbX9A^72*Ss|&Fm(Ox~Hybo&1}M_41fJoz+gND+P6LF)JeiaV5Vg`Ejek=NrX=Rcy6b(`Px6jnEv7wYCTdteaD zopZN!ugc~gb^_g2b^1-&9KmEB8ASuZUmEb6$-W1S3M`YoGFG}?V9lKll0J;&mwo>v zibSjxAhb&tVRseRzkp}g$$7>!`sAE^X#v^++-5*sWP$yj=}E^ zSdq$oLFP#=`O0MS-d#)Ua*VN@rz6 zv!PLULXG1QP&ll65W1)-cN+5nW*B;XW#L&S?rT)Qx}P4-0&#S<$Liz_AfTM=@^Eb^ z^aW&h%z|rWKZ7$QrK9W0{xLD4Rn^+Z6T(Yg46k=~TPb85QC*9wrF&WxtAQie;J_4I zkvM*&(!o$h*dxxwLCFfKjYO36*EQqU`b&O#@TPj~{?CLYb3ze9JLfqeJYlk2QL?76 zkc%00niQIi8*{e4{7Y44(ejy6z6&N~7tpP>!h~#7RLC?YWO5zT4C|{gA+2n?rj*ho zO(jgI5t7P#Ycz=WNFXWgdIdiK8zn>vuzJ)aN^`ImI`+&nT`;EZ+!+>@L;Gf+)961% zf@dRZ8EMB^we24hZr54u|MGFk!E}uaiy18t4!IISBH-?jY_AxAO-Zskf2QBAL%uVYaZ#K;i|Avr`kIm{Wyfz?j<+6oA3+u8D z^Nw(LtA%~fhb`i(X4aDMC^`zBWe;7ekuG17vufdDRk|$yEVjIxp@4m0^;bqu$Ca_m z(-vx}-+)9V{oTh$WfGxRhA#+oavcpOldY7RN}KG_stg8QgX5i+d4d9^L7HGp5tY;x zF!Y!+HU0(qU<*T7S1Rj7%sUCjrsD=IY5tsdoCN4d6qZO}>~nF-4;z}*P(i)}sa>`_id|=X*li;cq!Mi4i(c6~=g%{o-UvDVJ3_ExLC9;R zd*u8mI-f&M>q6I9%?}pyLe_=JOIVl?Fi(_NxM|@swT|twer$nA5io7~){wU&JBI1h zF<(f0BNC|5I5?CT#6srx93if#S)3@1sI{ca;N`v(hwhLZe`0V31=JBCLy{u%FE&Iq zJ3b?5?7kh<>%*26UnIrSZceVL|?=Ou|%@` z5uU94$><%ugTaXVan6V&R*8^%%|Tm6>@vCxBSFY7mOV|<+N92$F~oI74dFmHZa?2c zo5eLmf}v_VyA`z{Pr=YIz9lIQgjEubP!sp0i<{8aK1l#ZmIKoB6Girl*~(pE#3J?i zm7BUiy!tW#X=PDzYQc2RP1O*1EV%J8OSzN9*hr-(JFt8nH@~{VaDTl=boxyrYNS7< z9#wD!WkpLuqnkkD{A-VrCE>130V($G9&?X9jw=_GtR3u==HGfG&As)w3opF&V4(y$ z%DyWeH~;fnk9j8St;f}>znT=bAuN{5SB&{v=0nN|hs5X8LrO4G)Q{7^y3)u>&!3kk zK1HkX#6@vM>O>&gn^6UeWledt0N0tWA-(JYi1U|)r3FG!!ChApIK+w$ZmuFpegwz2>+9y`=TcHq z-rnCuMn^(ILOMD+EiEn~AtAlJz0c6nGcz;A#m3Up)UB_vr>Lo=rKXvgnU9c?i;Iim z;R<0n*sHVxX1Wu=dDmb5@ zoduu*GO7Y3gN)R3LlCkA83ANu{udpGM*u$>gP0`<1_F8BNfnW-jvET2ri(~grcgs6 zfuNc}C`52O?KU>*_xBwlz$`(9h!7a5Xz`@Dfk^XqtL=`O&7MbyN*s{1cohspL^?w` zCJbt{9v>V2SM#J8C>P7Se={P=10MX=2jpbh>VWAOZ`4loT=P^~`R! z;id=$u@Od+m^K=9-@%NRBn(CZNpZq6&5@6g(`ZoI9)5wt!^aKD^z=@#Am195`0Y`!+$%p9c^CoEQgtOp5 zEEcDUb#KOlSex@S5iLQS2y^-+;ZIF|1UAxyZ{Y_TYaYbh#94ll@a=j?n6ogKmGGQ7 zu5N~n{5auRbxdHR(d%}*Gge|&-)9oTqXZGC!A?v^)WCU^aP1K#u)#ixQOY2MYgwb1 zQGiGo4k29I#st9$vMx?gBP7Mh{wQkmjt!+NK5(D1jEohRaI0HZk_dBDoB@dwAf&fhv$fjCdZNhQ<5A@t3*Uq1SKU_ z388}$(?g;PO09|sv0Oq#KnEqK1Ep+20b1FF28^-^1E7+Jp&@{vRHh(7OdzO~Cn)f+ zMpa5ed{x3CKtw zIjm=9~S z64&923<&Y#NBx+n|9Tn!B*WlGV1p8mZ+|0G)5x3`z^_<4m%OOPtq+R zx=*X^VHnsL6e7Z@h#Ade;$UE8&}ApcOhraO2-I4UVPIpA^otN=7>BSx2vohCaMdIv@Ur#r=q^%~zIp~i|2G5+~_YKx?`GWihq zr|&?z77t?7{=eO->2l8W0;7=B8p=plgrXCrz;i%N;_+EX@Qfhv`MBi>a0xK~6byma z5miB?_OlZTfAvRngQFlJ$A8OE=PEDPSfI@teg&4n|@EB5r09gnqfi%%sK5sU5ng9~KoTyQO6214=+ud?G zp#(K*ml1}pP=FHVpWU6m`1Afgr36jUjnjmoig`A?7XREdef;NUcb{vwNmPwbLd&~Y z&szSTYWsQj{WLKWiHb4C6Z00000NkvXXu0mjf#Rc%Z literal 0 HcmV?d00001 diff --git a/deployed/regularlabs/media/modals/images/colorbox3/index.html b/deployed/regularlabs/media/modals/images/colorbox3/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/regularlabs/media/modals/images/colorbox3/index.html @@ -0,0 +1 @@ + diff --git a/deployed/regularlabs/media/modals/images/colorbox3/loading.gif b/deployed/regularlabs/media/modals/images/colorbox3/loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..19c67bbd0403f3f00d71bfb21a59cb6c55d482ab GIT binary patch literal 9427 zcmciIYgkiPzCZAtoosT0Tz3eU1b0G!fDrBw5Htw^q97)Kiiq4%u!yLj*s-0kLm&y4 z1Q6vW<)-2tyh{}UQPHA;Z7o&WBHAgf?Nq0o8RyKLp8p2a{^yOIIrBUxFL=R|hZi4y zzwcVVwN~`*?u9qtRSk zTrOO=AeYNSLqlU@W38>NwOVa@db&U$u(Pw^la^y#OcUb=KCDJjXp z!GXu)F&K=<$jG&8*QTVTm`tXutgO`3)UK|swzjtB=H`P354N|rXJlk}czASlbR0f> zSS%I?1_rjawk9Vh-@bi&U|`_fxpQ~#-W?wwU%GT@ZEfxT{rlBw^`1R@>g(%kYHEx| zqs3xrXlS^0?b`M0*KgjudHM2XiA3V>@2}VEWinYsMMZyq|B4kW#>U2~s;X|?y7lh6 z@9y5cJ0c=taBwg`KmX{_qd7S_pMCb(Jo&Fb1iv^$Y|qIk%E?A{38Jjao^0#JW zOY#afZUqE?BLEQgWx@YY<02CiBIN2wKZy?>hyBWP?r+Tf69MA?XaQ7LrZ2BB7)_N` z)iq{IZCx2PBq*RBrE>*3C@^#htBJy}6WXG%a7lPzn}y1>x3i}Ku)~REC^c9H)_^Pr zdv`lOASi697*L2OBxbgwgNIKSK;WV52{CNpIXejb%N5>YX`N`X?@&3v(M*B)Q1yRR zf>zcn(O$;>9>9Vlkc19}?Q)3jnj{wDPOcY%B)eSYxPo~$*OtjqO%D!Nuo0LuC`Sy# zN($UP_Q}0Sq7qIG^%%rmugue{j^kP1u0KmgWn&|_xNn5uL~1%Kbovj`u#6x6e7S;= z2rF?fDZ(F_5Tq+mQo+hY$RRPKzu!xgj!s=F`RThaKH3$JymG_64XJ|8HrH@HlGfK( zQkZMjr9e$Os;`%hAA3MU=>QO$`*;AUt`jWe2^zbAQCEMkc8W6wdiq&{#mU- zaVHu=+e;=+FpTfY{KD04M>rBd`pJK1k7PWm{Cza>d4RFAr>o0bMH2RUxdYkq)Hs%O z_QrWc$0;mdQK3-XEvH`o@{5lyocijjmI#5bq`5OtIj;IIT|wzW z7pF1Sqx_U(%uayLH$y>bj*j^N5_K#JqSzELrDm>E+B;jk0GhqsRzQ^;UYKB(EOTOH z(g4US58V=;6CKb%RetSO9-XAT*8&UjAZs!pJQa__)qsBB3-me+lh_=#EUWso$uFMz&SSU#wOGz(1VlWfhulVjuj8h~s^q0dE({U3EZMSyo z>$W4j6-i+m!8cc{G{Q&>=^c&zHl(Etq3HOT4)*DXx&XQ|ZZmqo!6T~^ph_CZB%%!& zKo|~o&H#nwzJh076=ZGWBnJG|nh0R^_I07l%zSQKh|^*KieH5~e;LYckUR z$0>6Uf<)+x(NM8x44~35!q)cy#-4oAliLSkF8r}a_Ns!Qx8g_^=TpqpF3d##hDyYh zxzZVIG4gkOkcps(H@#t1z8IwxG1c#MQqu}F@ipw!WvV;?v|%nU0w`%Yo3_UdEVhk| zBLKze%zR+k&bw=hYmkJkw4n6>wJC#wP>nk zYVo*%fCI7W$eloC6_KzyS1FHR8moCe1y6faBvll>V9Ls6WcZ!{`k2ZS9?63}HK)}tYwi>70JrlLF)s?P+l=leeAn<#Dlp8=vAF@GW7f%oh zv%YUX7YO5G$4h)pc7USu4;M1&J#1}TXf><1LP2=ExhCIvi{IW##Cl5>5o$J4cD1Ep zPJR)vStO<(IgnBW0wO2(g6JB`W?ybS7`-Kh1yDFXxjVDYSMdeM{H1`Ob5s+}eJpI5 zndfP>SO7r5^^kMH&K$=RH3-3TJ+C}+ZO%KQW=KS>5U0GHRwOzzq%VDia_wMQBzti3 zR(g6Z$`$+FSC>5<<1E^ut{(2uFmXZTq^b0?(>JOsOq6K^P?iq07$_I9@CL(H%!Rk6 zmqD(Q1zfpJVvqRq>^1+${~38wSslIgIm|kj8wLi$tkFhT7K7Z=()#5))#6r^>6#6L zTo(CM@!Se`;nbUQBEC(j0s+l6^2lYf`l>~ov_(xOa2bbTT?c^Vd@Ozx0Vt^KBGxH( zY3x;I`6_`FfM}e+Xb1@@@o>*PR0(>Ey%I!#U{{eB;D6CQiDs6G;|0MeyAdj~clSv< zR)g?nsO3ucr3^*WiBskL;>9U@HWM<@rBMnJqp>$vVHfO>?Fr&+Ak+JXKg~`yDoceX zTW^oh`(4>=My2i4#Ub?so}SoKW=A@@t_zfWY2PV(oKT90Q%Rmm(BaT>k>Y%nh!j2A zW_C*2^Wx}i^=gHJrjMSs3IqtAPOHh?+I#Zg5t?7jj&VXIk^acmLza1L>chExKxHuF zRV9($W@NThQ1S$n+R6l#wcmat6w$m4LP1YIzJ)xrJXcprZixh~w13|}TFzU%X0KKaZ|f8~u2XDI$$lQCh@_7g zlK#Y)?f~JvA;TB$GNAYVieC0t&Oj8TR;67+R@l=DrHiQ%{DT`zo?Kdl z4)oqku^0{! z0z_zB)`rB8gEh#gcR)Ee`{^?bW~`jzw*GmG38c#vH;iQr#3zGkad1c!{jKhvMT>jr z;Lx9SSZH4C$Kq%kV>1PWjf&>JELklT45oOz+bf{3UE>I|{)z3nJJEj%MKXPrn=T`_ zu|%q!j&bZbclHQDz?KEM)6}weEwOxHeQ*(FV&5|+Y42A6LuI8LM;)cW46jJ{J#y~9 z*sh{yp=U5C)wB6VOB;COMEMOT1gx!6tnw5!mSb1V z2P@D6>k|NIu`A;pnt8!U;bp}JHgg6u*PEr+F(XOm9cRePf0s zqveRF+Y1bdDwF-ipdb*M-Di9%RiL#UvvmjY?k-HfC4X;0P)z$ zZ}UNo^njR(BBzSSTvHELA+6rm^qYxAG=424d8|iP3BGBr1VvKmGlPUcU{}hBS=s%v z!G_sHHwROVk8xP7BSuPCL@@!ry(0gi&@UCvJ-!-a_A;g7NC3I@{RaeP#_EuPvikEXMOE9$hFTJPD!@ zUcuP>3oud)M*9E3=tMmDR~MP5mB7M&#d1_6@GH)5tf9YB;a&H?Xa+Hqqk3uaBJwzv zK99n-mP!v;Ix8;e_FOMx zc@OmBv}Hu|;-t7RP(E!%P7;S%+}o#PnhvK5jjSR(RC@x*Eg9_09(3Elg$>%7!apbA zSk$QZr{+gC%bO;n{U#L1rb6>j)FxfyTmk7|NiCm%l}{H|K5T5(dcy=?ZuRoEP+JdR zm2+C`wOM9?Frz`e!Ye`CfrZb5a>f1+Di8Cg4D&#W#gTDAi%u9%i33c&L>msrX+8YK zNBd`o_v?sR;`m)%2ZREpXzJ1vfD@uX{C4i>`^Zws$q(I0RooE@9PI-Fd_Fgf_*Sf1 z;XaK`P_ku|l9pB2|@d?8thohhSCo2yHHIVrcQXONc0 z|KsJ)Go~8hp~qqwb4Lm;pzDNS_+S#K-=eK zy!V^wE#3#`+e*=L!a}`z005CwSC5+KST5@autN|?GF}b`v{g~yo0an@{Dj4e7ROf} z7e6w3u8vfxmOcOA>dT4*>tC#cQpBuXT~mX>s(ePq%@Y;?0{2}K=NO`_?I}VIX(l$k zW6??>GI`T5a%wx6d=V5x;bD*6;-I5n=dY)QBv}K6h$4dJvDm2;DSX0$IHA*a?tnsZ zPvlCG)lsyBs_u;L{^y9$1g+Xq_luo!2#8w6uK9=M^WKH_ih9#tjDHP={RRd>eubfX z;{z-h%v|6E!POlV8Yhi&KCnhGwXv8VW>$=h`1j# zlRMRM|Lf|*%rzx@?LHCQ+1u3UI$5ZF(1GO+^yGHKn?z>*3o?p&6a7~iXijE7Fjq2k z?_j>AS?qmg4hB%Pi0Q9o*jJC%K)myp_46lZ^P51dXrP1hFqM!DkC%;_Fc~9#l~-Qg zgFjwXN@}Z<{f^8o*|j;sIw~QAd0@nc0v2quP1xfzkno} zM-nac6*!Ny&{uRk0hvR3Q$AD-X$a^>F(a(8&SS+hce*&&SbWUrVD)@kL9!1&#hPl$ zc_BT8&XSo^~R)caht5PLi@cUAU&OSE6mI3;H_y_vz8VUKYb}{>?0nXH7OIm zkTJ-v?#eyxpAMnMCGkGt)yYp-4juMy z<0$?K2daCMIdnV^{MF`Si};9{I)JU?-2i*wGKO>Rqq5gH`Z=7Nuj{9Or1BVsGu(3i zyMZ4Jih&oV1so|s3OtKqsL1xGDP$7*q@|0z{M}La3~`x`lgA1@dOCvG8Uhf)E(vnW zt67VZWquvbF-;u65MX}|)H)D?40}qR_vp*vI6{#fJIBZdpzo$dAfe7uq}ZqI*sg^Q zUdybtgK(g!j`CH(?oRoQXM9xu$C4AeeGDVLm~{T1ap3;|hZ-#ZU*a5ig@ZqBdN!|9 z`AUaW*z?&5M;g)XDMz@?{XW5ET}hHpQG`_`@|6R>)cJ5M1VE{0!NSbz``n%RyDeEa z?l6GVi=UK$GLxQ@|B1HbX9A^72*Ss|&Fm(Ox~Hybo&1}M_41fJoz+gND+P6LF)JeiaV5Vg`Ejek=NrX=Rcy6b(`Px6jnEv7wYCTdteaD zopZN!ugc~gb^_g2b^1-&9KmEB8ASuZUmEb6$-W1S3M`YoGFG}?V9lKll0J;&mwo>v zibSjxAhb&tVRseRzkp}g$$7>!`sAE^X#v^++-5*sWP$yj=}E^ zSdq$oLFP#=`O0MS-d#)Ua*VN@rz6 zv!PLULXG1QP&ll65W1)-cN+5nW*B;XW#L&S?rT)Qx}P4-0&#S<$Liz_AfTM=@^Eb^ z^aW&h%z|rWKZ7$QrK9W0{xLD4Rn^+Z6T(Yg46k=~TPb85QC*9wrF&WxtAQie;J_4I zkvM*&(!o$h*dxxwLCFfKjYO36*EQqU`b&O#@TPj~{?CLYb3ze9JLfqeJYlk2QL?76 zkc%00niQIi8*{e4{7Y44(ejy6z6&N~7tpP>!h~#7RLC?YWO5zT4C|{gA+2n?rj*ho zO(jgI5t7P#Ycz=WNFXWgdIdiK8zn>vuzJ)aN^`ImI`+&nT`;EZ+!+>@L;Gf+)961% zf@dRZ8EMB^we24hZr54u|MGFk!E}uaiy18t4!IISBH-?jY_AxAO-Zskf2QBAL%uVYaZ#K;i|Avr`kIm{Wyfz?j<+6oA3+u8D z^Nw(LtA%~fhb`i(X4aDMC^`zBWe;7ekuG17vufdDRk|$yEVjIxp@4m0^;bqu$Ca_m z(-vx}-+)9V{oTh$WfGxRhA#+oavcpOldY7RN}KG_stg8QgX5i+d4d9^L7HGp5tY;x zF!Y!+HU0(qU<*T7S1Rj7%sUCjrsD=IY5tsdoCN4d6qZO}>~nF-4;z}*P(i)}sa>`_id|=X*li;cq!Mi4i(c6~=g%{o-UvDVJ3_ExLC9;R zd*u8mI-f&M>q6I9%?}pyLe_=JOIVl?Fi(_NxM|@swT|twer$nA5io7~){wU&JBI1h zF<(f0BNC|5I5?CT#6srx93if#S)3@1sI{ca;N`v(hwhLZe`0V31=JBCLy{u%FE&Iq zJ3b?5?7kh<>%*26UnIrSZceVL|?=Ou|%@` z5uU94$><%ugTaXVan6V&R*8^%%|Tm6>@vCxBSFY7mOV|<+N92$F~oI74dFmHZa?2c zo5eLmf}v_VyA`z{Pr=YIz9lIQgjEubP!sp0i<{8aK1l#ZmIKoB6Girl*~(pE#3J?i zm7BUiy!tW#X=PDzYQc2RP1O*1EV%J8OSzN9*hr-(JFt8nH@~{VaDTl=boxyrYNS7< z9#wD!WkpLuqnkkD{A-VrCE>130V($G9&?X9jw=_GtR3u==HGfG&As)w3opF&V4(y$ z%DyWeH~;fnk9j8St;f}>znT=bAuN{5SB&{v=0nN|hs5X8LrO4G)Q{7^y3)u>&!3kk zK1HkX#6@vM>O>&gn^6UeWledt0N0tWA-(JYi1U|)r3FG!!ChApIK+w$ZmuFper zAF%JpeZBR%PujJ&?cU$mzF@zQ4A^OFY-v$p7aBuKlp}eWDguO+1d;SiQl=<_wN?Ru z$}F)CZO*|QgDyN_U;rRDpw2LP$OLZD@3s^O2w|jPHUa@DKspfu0^h+*kZIDEfdC1N zo&f>EwiE)lfoMlz^h}7DN&?yjR1p>l!e}9cKf%uX+@UK4M1f#6=sL9_;DREMkOewV zfoO+dLI7s`|J0@eorTef?let$#kA*uOgea0n8ZlkOee&KKj{^r91I77A-eH8ps|f4 zR&?ZffL&>V(CCVRrvEA8dEmR#;6Zc*yd|vTX9rg5T7axEP5v+4Zntml@9#g&NiFW~ z?mj*|Jp4E|`@kX*eYOBf8o9vM2x2{|-tBguH=E5{t@UOONZ2e{4& z;l%aj`Xu76lRR)cL2`%#edS`pxl`^D?M4w&McV@gar&!0#ef2FI8(b z#DWlmm{Y_y#PX{mPj?a|R4~TXasN0V$FYKyxRUf(A#@Ibt8K`1v19a7GHVLjpv*rykJg@YO(c90K=lUwwq8p*)1_eipDm!ER2ms;1lNLjj`TTFBVX&~i5Rt@CB zKy)o2>smmrY5{rGKrRgAbrreRZnyhd1&FOAkAKnU>`_;KpIE`X&?=xfi#c? z(m)zW11T>$=X;6&QrscWyDBVl)L*rL{B9r@2J%=7$e|XHz7~+7fn1QRR3&ddR0UFn b{1IRPnb~f(1W%SC00000NkvXXu0mjf?Cjqi literal 0 HcmV?d00001 diff --git a/deployed/regularlabs/media/modals/images/colorbox4/border2.png b/deployed/regularlabs/media/modals/images/colorbox4/border2.png new file mode 100644 index 0000000000000000000000000000000000000000..aa62a0b724371d1f0a8e183c5f3707d2f7aecd63 GIT binary patch literal 170 zcmeAS@N?(olHy`uVBq!ia0vp^MnKHS!3HGfT>QHUNJ*BsMwA5SrjnPU>t&Bgig1lwFnk>0^Moe(#2j_SDR=qm2cFWSad{!^LK345wm0*~eFZqAj Sx%>#AxeT7JelF{r5}E+(L_S*p literal 0 HcmV?d00001 diff --git a/deployed/regularlabs/media/modals/images/colorbox4/index.html b/deployed/regularlabs/media/modals/images/colorbox4/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/regularlabs/media/modals/images/colorbox4/index.html @@ -0,0 +1 @@ + diff --git a/deployed/regularlabs/media/modals/images/colorbox4/loading.gif b/deployed/regularlabs/media/modals/images/colorbox4/loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..602ce3c3ae9182650eca594ff76e4c27498f39e0 GIT binary patch literal 9427 zcmciIX;>5Y`Zw^&kbx{fLNXyN2~I-9fRL~W0YO6u5M?m|q=?9_f+C`VVvlXZgg_P` zVN(!LHWhcVE{Gc-Dk>^?tcNPr2)1rrw6(4Mw@>>Fp!Vq-d(LyN>(5KC3txQr-rxD% zznO>y;i7i$H&JXJ$m%pZ@=BRabx%H-3JdIymjl=>({Tp z{r21a`}cQrbeuVJ=9_Q6X>4pPEiK)%XV3HJ&wu>!$M*L2vuDpGFHr(0TDMn*;+Jb18f-MWH; zf`Ng7J9qBfyLa#V@4q*hOnG^ESFc_j9v<%R?|=2`RYOC=(W6HvCMKRed$w=iz9mbR zBqk=VSg|4@Az{s$HQn9aPoF-0{P^+9moG10zI^J`spH3wS5;LVK79Dtv11>7^igqf zaY;$ZmMvS9N@Z79*Vx$DC!c)s;fEjIzkmPs?b|Aq>coi?si~>i+1YE?u1!u(PD)C; ze*L;$uP-YrJAeLsQ&W>pr>m^2tgf!EsHo6rG+9|$nVFgC>FKLht@`})&p-R@v%0#v zYuB#T*4D0Gz52q13(J-*GZ+kMX=%;P%{zDQymIBr%9SfSJ3EVtiVht*w0QAi;IBWN z-yK5NFHbL6o`r16Dac0BSEU!_u1(JpJoB*pKlFHVRBT^oWQxX1`^edYm36% zxxsUG7|AyFcJ|f)>~L^CO7<6nl_1T*-qp?<@C%y92PFIvfr0Mm;O5y5;8`ergby28 z&JJ9kQi+f+s^-o1>MLc}8%Qu4s`wv0Xl_a4)l#>00!AF3z;(!P34tgsiF_{Z&{8f) zu*;SXOKgs1+uAT>rr!QCIs!9#Ll8~BlmvGS-M$%SA%#-{-Fk5s^*L(U0W;durN@Y< zcxV6@^Oy^cq@>XTO<)LCnH7iK10AjUZp$`goCMgiK z#lQ<+7$rYSicd&d)`D^MltU4b(Tb=zVDSe*DHzv1fr0E2DR&^CvAY2JJw99`c8Xlc zoZ@PgczItdVf)q~fd^I%2o+>*nDKy}W=d;xW}69VwVD+RSIIAj*l0MmlBDid*}W5$ zIwj8&na~1ZP(GEwU00<<4>Sq2j`U*5coz4 ze4kV)FJ?Y$sGtQcx2)5%BZF2fL>g5RZ@$VmI%s7SsU1KFX_=uYJAS{s4Pe&^Qq!~2 zm`AeqCqpEfj~J?iq#2pZmbnA-=Vi|T{4zZF0t3%7BiTj7SP_F8_RDVc{f+A5on!4`yt6bopinwAmV+4z3v zXM-1&Odj4wSqAr_jv;tBs7Up7OGzLd7p0uV%Nu}_zro^!Nu4dmCU9yJ&ED^{*cx*p zB+iSd(~~k2^Oj*wkbj5@&PvQ)NNPuCr&5=q?BxA6Z2*OBfc#P&9diLBe1AAZvdXg& z8JJF~tJin{*7kO50a;RTew;xt--()G4L}|_=$hc=5x#X~>6f!gBNC-I8(~fkWJv_L zhhuTLO3)j8iC%1p%UQ3j@iCHks`^ZDd>U?Kdh9+}`*!T`??sZ>hO!M6G6gpbLt3q{Uxzf7AS4w# z!@)jncRN6l#;ih{9o#b80J5NtNU*RX0tnT?&KV%lToSXK(UKZ=Pv@8b%Kci_fo(7x#@5tn=dRwEYH}C?^EDZ^t`d&uBoy6$#s2k z8<*sulO-1Tjf{tdN&NfWMrzv7W>xH<&Y$gycq&T}kg@q$4^EoB3$%dl4+iqxBLSI$8nm<%(01k$CayL| zp8U2`{3b!rdvOG_b4iAZnKto0b$Z0bCfXTn)Ur41%s@~?NU2+t%STBCHuBYNc(4+|yDw#xhJCPn zHE%n_BbV`$Uz;TH&Q#HBFK&pkwH1&9t|;OtdUprcPeafe#FGF zv}2}A6=gb-2?30HjQz}D1LuE+Vd~r?r z3`XjV1|2w`LA9&~Kw>UdKN4RQl(t(`OExL&WrmPN91#FnGv-7bzeAQgh_ixpA8WpUGFmS!=IU&PZh^Pjv*=X4?O1o8e8h|r-&tZu*tet| z6ntUdCVm)KjPO$k?o!ZU_X3{eL^+QTF}TCvl(^;Pz9$unB@%0OgvopkfOmIVOzcqJ z4DlbZ_Kw^zjMrOG?%BGDGxm?2o;(NW{i$z~M0lT(!B|Gh;gG8IaWYHqZCWUF`+Num z-M!gH_ErF7$^!gAKoDUQJ<~uJnn?htP`0TXiHVm-QID2G{(Qa=288noLLhWmbd-aS zL41QxL3!g4?QRjH6Z5$#C{2kfa(ZEe1S6&FrG>uD<>II(7iEOWNej+a6%!l7Ky&4< z+XhQnvlD8Sa(G=E*KvttRdUvga7h?tK$G}A)zk{YwE_JnZ&0C+en!vuNXH=(QYBN) zB}(kA^F@xq`9F=P-gN9NQGR;4veydhYLVIGq_Nt$YH0ZD$1PogSt92rN98zLJn7zK zA04`X>fJMq_xi|5eAey-MX@rTAJHn7yc zfHbo8xecNA0YH_RONUWM5irgwP<@RY{~x*w?|I;-7?kY!)S#uFd*?*@8z%&;DwiyB z=hf-(Io|Fnh$XH*V5LkO=)HX!FuI0GjPWU2SccHj;Rl(}7it-i)ON z(M8ONYTD5XvNKY$ULCr?p@x=@ zmc%0(FJ>t#d&JxPi8JjEK899nu5)60A;J6=)_^w2Pi@!RUPjrM$Rf_;?Rt}DOBkrwx56dz#@lDv*^FUw*gcpaPZ9I?Efopj(x z@hgBKp$YSvLfg#tn#mARb?0Y90svW!XvHCY)L>P?d|AA5QSn!`NVs~?nk^Y8d zACKc*m|I^-d85L*=+kWgF_e93QQ-{YFxEczN<|?LcWNMC9&b=PWkQx(IJwBgx-Pyi z{L$!<-4!9c-?u_hkJ5(fJ+0U9t2edp;L;+_ZE46fE9;S9TWqH9p=}(}T0#AmctqyM zEUoPB^M3r9Gwqr?O5iKW6yJGI_(dJ=OT{$dxg$7biG^WyVoVSiVlpQt@`H@7EvCqZ zJtr zu*Wo0K$6*EF@7@+Y7g^$bzT-$42IKE`2MwRPx`m1EHe4Ao7$VX94T+?)C9l?kRaY0 zH*{Sy>KVC#8_AOET#lo?udnClngOq}MGIX`Xc)A^jB6h}SVz&2d~y3<_o6t%wg@Dl ziuy`&vC<0?7uo63OO)BFq}QV%<~3Bpyx8AfzZ%z7a(9oG{3d-Ut7~FTAF>48hQ)4A*JZL1JZw5f*@cDg)NtQF} zbJ!&aBp5D*eRq_T;LG|c6n5O~8M9;c2l)52?u)}@viUD|o_}2yXZgFOUoxMzseP>1 zUzSTvzkJXLK;YI>{N6zMMf`c1`e+Wle$4pxEbuWneVsn%iN{b z0g0ACJ|YRFxy^PeM)D_U5F^lJ=L$$9H+e23aWzSaFYie2=y`!~bSZOv^Jru>PfHf!@0XSD0C zEal+Fx1Z`=t|_&gvkPGm!0T#`F!OHw$Q=x31Godg0ppQ)!Mc6?qImLMcYKi4^s9I# zSTFK=0~3^RHJ1-?4YZvB+&~>4A9~AgJbSG5)|VA~Y!ZrU?QV0f*EZCihK!^}NBL6*nv~fFOh$$x^k*Bl^M#*I!T^#+KIN?p{rtX4h;`zOdg|tE z>JW&92HG_Rqld(1X5v8|CZnY+^2o`#^X>VUnh@{by$`{d%!MW{)gz|K2=+H}@{LEX z-@P=x;DRPZE+eKt0r8X>E`jU2o({4yIdZ$X!@JF!DNM(l4^;O+*Ory;P zS`heBVrhnht4E8|`xEOt=YJxm$t^8x=gzx}w3`NGjdu06oxS@O8_^0cXN5fD@^yBZ znkq20R-5OwTJXNcPC?t`Z#R3|zkwu}LgG!&6*z@7Jy#SnJTi&&E7WpydB^kc7fDoH zsko)Pm>T;jH}PY;>b~Afwve#|@%+>b?eZ0t2kgy%OlT~vSdsV?x6)k6wXfv?X=&D1 zf;^mdT`{>Bl-7~4rc;?i*H{$VsF?dwOeMOwO1HRv)`x26#(D-vOem{oO-+1ELxowI*(z;auY@%o^DULV@Elz==|SG+wvbED*{J&4qJyffR4t{D zaN@5x@PC0r_7D00#A$wmV|G;cd`d_EMu(8!`LBbH))uoKF}UkoZ{cSyDN6J#2sPIu z4;OD07^Lq=4V{o>gvqiY|OlLoeHFM-!1~hIyEErwzB9Ip0tAt!Uvvabl?YF zQxcj+e~}Tq06~9&c0)<6l1bc`zTRd}WPOnR=@IJ0XW@O4h%*i%$8S*F?p$;1PKb=W zT~8VR6^*#V@NTBC+?<)t%~ATfUaWVHUsb({%}wkEdPn)ucd^-v$=uWO&iQ|#FFe(1FkXaR7m z0C|ZK9q)6t;N0&_#F->kL^A*%&{f^*Ox!ruG3YEV*3NOs-u=k+YE>;kp&M&cWLmK+ zW)=eq;L1f&h%a)WA+&_UA#J#`r7LZ#(d_sttGm{1h)NA$cZy$Gy*(7#{%;DM@~30H z+_Oz5Nn1FF=C9+O!|Qpj!NGH9Jb78pjB=ebN}3ds^@g&OizZfNqiQ=$NMu1Aw434f zJp(P{-f`xv+0sF+vH$`y0Hx(W9^o&^_=P}jm3$W?0&a6CHdS*&VGBs?nQeMh(n7rD z6qI2MQPpT*p6?(%jtc22_=BR>-e=9`gi=o)o=X|^$Ryf}OuUszH7twHv(1s)^4?Z5 z^FOrN0gyu89CUbiG4yBYoNVNuHjvL^rPBq_&z{H9bL=nasgiV7Tq>V!=efFB3yDwN z(@E^+ez#V~JB#tyFIkfB^Yz&_edu;gz3QMG$HJpae~y*CAw#bk0@nT_ObZjqL=+k zoo7XJse5G?!mB9m=7n-#?*({HGOmChJD_*al;F4UGjLFnL}Vr4CH|Z+e4(f4hdb}m zWB0!%B$yNm<=Qz<3YplMYM22l!rM2-+-!nGAFcMg3;i31Ru(ee4rj(_1JkgtZ5 z>Fr7-C-k=5?1kwfP+qDj$@yV-Mwxx+?lETwj4h*jloxk<^7;}qXrg6+m*qDI&F0n}sD5yA>cEKglDG~GZV>x*S1&Nx+Ih9WT|v zp6l2-#dK1evT5IN+M>HOJ z7^$WMq$4dCX}xBf8SLx%S4*3KImdp-iOd%i*J3+Ws&SUkN_t|K@%X{XZQbqN zq1oX-5K^(RUA>XD1IUSCtF?^dwlf!5tII%+}cbe4KFNOc|^O0O|7C+J>;|`Fu{Ckv6vFF%ukw2!-Rk-qWJuk z(=Su2=`)uOO%q9cO}eL=oDEr#HcqWmL1Jr>ISPe?Ly?BhwfUOC#T9Jl$BRO%jA>$c zf!E0H>jcLisEl3?d4Nk5B#V6tHR0PGpW_vFPY2cNp!s>&g`vl|Gj(lc{4Yugm0$q! z@s5uP>KeC{j37X~L42;PF_3XE<6%FL(3mUewm4RW(sQ#wetu?6Uze*r5gADTCs?hv z=I5J+8PhjD%iir5tp9|__brj!e(|3~7Aq2#d;duk5wtQP;4Kk7D`;ckbc*OH-qS>| zV2UW#A|riWz{C_0NeeQTEwhP?6ktS_nsakAX)dfbnJgsC%&y*Zq_;0f3gr)iT`~Z2 zU`M$=d(m&=kcOQUnuqG^W}&>J4O$t3W{H^XK@M-iqkM_=Amb)<3~2HH>fYw4Gc@vCS*&oecYLWhhKRO$nJ^ zk{TV$s|Vs16wO3ow}r8+Rz}_jc~Stj&%$=F$rKr4Jo7eYn*%XxCf6|j(3MI`x@UF} z1Erq@=tKM)mHs31Y^RkdGngRONXBpBQT-2EVZ;V1HRiiXBLZK>LvC*OTQgvn-mV$& zLw+}IX%JNeWFBw%nAF%#{~ zxE(E{cwk@wAUZKpU@v*1-xOp~AU_ekvK=&&p8+7HI6Q=$XX?Bx>jU@u*FU65H`1sp z$dn`pn&-pqZ(d=zzC9y4{jCu>%!gEiN|>CIg1Lba4WPx;*B(W4gIyYYlkHvICO`H# zAe~mSbg)mH`qm?H@>`D^@btGHG!#!k={NYphQEI6F~x*^>v6vPXPv}0fJU47fI9V- zdABswA^wG_PYQwf3+a~5n5qpF(alx9uGtaspT+V+>lcRFr6t1!s|}J zV(MjKaUPeKcf*AM_R%8zx0e${|KJ!NE32;W2m#R=yx+=s%rUveUZq|IbP0l+XkK8G}75 literal 0 HcmV?d00001 diff --git a/deployed/regularlabs/media/modals/images/colorbox5/controls.png b/deployed/regularlabs/media/modals/images/colorbox5/controls.png new file mode 100644 index 0000000000000000000000000000000000000000..65cfd1dc95c5ee4c6c3d0848b1dcfc0ec69f6aea GIT binary patch literal 2033 zcmVY16Dl9G~IT3Xc9)Z^ph#l^+1udkq>pj%s8x3{-FJw3a- zyTZc4tgNhJVPUGOs=2wjTUuIPU0s)#m&C-xo0^)sxw(yvjeLB3^78U4D=RH6Ei5c7 zO-)TME-o-IFwM=)IXOA(>+9v^gnk!Dk@A&OhZFMI5;>mGBP$cHrd(PIyySo z*x1a>%u7p4z`(#lLPF^0=SN3JF)=YpN=iXNLGSMFH#av(NJvFRMNv^v@$vCHJ3Bl) zJTo&hNl8iR>FGvBMo>^t>+0%WUS93(?OFDTAPEK`obwEHsK0ZFDr>E}i?Y_RgTwGjIQc{VDiO$Z>?Ck7QQ&aZ#_VDoVc6N4O zUti|s<#>2_pP!#*wE#@J%|ZXjkIv8d15RfRBQxe$bh z9TUw{N+{bY1z&)8>k2t;d{xYxg76&eJ5GSmab7cm2*kJn zLPONkBzslPWkA+%7~Rthzj+ZdH;HAk-Pq6JDgZ%}1qZgnS8` z|A!BGUTY0vuJ8~Q8k9-cggFrxrb5iS-G06qcV|ScTS@l&{bZ%90njJ((hDH>go-Ov zZbB$mN3X(#_fF&Gsyr1MX$KPpfH2>rC?r$(w4Y$dt3?|Rbk9;C`p(jcaF$k70KON_ zQXS~iuoPW9OL=;PXDK^qs;!en!tGwM8Dm32zK3Hnob~aBRzMgVd)VIwFSb@T|pRnFQtL^ zQVJ_)!)j6(b&PC(dhopzE0a4<>r<@qU z`!EtA#BilIes-lde&oVm?AXss0zni9@U)s;c2)_BE*-ve3qd+Xkx|kwB9dCkgI$6` z2)acBb&UMSYiGCKj*SBn@)q-Z5n&E~kT-AMBO%kChC#@X|0tXb=fe3-(?1oCZXuoB zLi}_KX?F|Z?iRyJn&Er?*=Fkav37KPz4^Q2i%?hdj$hRY5$X6y8bhS1yyTxuueKWC z5CSWPU;%-YXn=qr((#(QE2FU06#>QwQ5V+BI|UkI(*RRqvv@oZ-B#&@=C_U&BCHmt zC#jJURR)BX9qafF9iN(TLwU10A{?j~CXS78W{8Uu@HZ?#PAyEpFp1S*%EGlpZ`N&L zTO`O5246{p*$9hz`Xxjbs;;d1D5fGugh*6-y27O=ZrgP)q5m%J z%*b8(_kO793Uc&AR^jAtn*OA38fGEGyOcr5Fk7$*{qtd@niJ25{6h8_pFvpWJ0e#STIxNJ)pDn{H0&eE#G130bNngTwLQ z{r-aw>G;0=r|=|0AtWIQNk~Exl8}TXBq0e&sC~j#A{E;EQlD^{NCv_KN?|hzt4p`= zmiMYgEZpwcxm$P_8++%CQ5bCMy}oe)uer?ORv)df%L>+~SMRSwxVo4v42N~krH0-D zsqp7BEemF3oQ#jZH?};MT1`)gSQr3NRVET5olgiEnaToD3Vmr;&eR^luC95&D|F|1 zySmIE&VwgJDV!&k+duls&IXn^h1S?O8(9D%7J?Dx?3|Gb?cRJt`cH*#(!#mIWIQCf P00000NkvXXu0mjf=5OWV literal 0 HcmV?d00001 diff --git a/deployed/regularlabs/media/modals/images/colorbox5/index.html b/deployed/regularlabs/media/modals/images/colorbox5/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/regularlabs/media/modals/images/colorbox5/index.html @@ -0,0 +1 @@ + diff --git a/deployed/regularlabs/media/modals/images/colorbox5/loading.gif b/deployed/regularlabs/media/modals/images/colorbox5/loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..b4695d811d4f84ed693eff7b5e6b4d61a3e8c48d GIT binary patch literal 9427 zcmb{2c~}$o+BfjYkbx{fLNXyN2~I-9fRL~W0YSqMAPQmvXc3WJ1&c@(6VN-G66{!m#Dz&KKu^y_lMYNSx+iL6S@to6V&NF~*-@fnlUXMN3lYjN{kB{H` zJHPuk6Sp8%7M6_w2=Fri{G0eK0q}qQ6Mu9M|N1`u%P;s)H-1oqA2;E5d+=93<3CK` z#|(Jq2l(X{{QIx*J;k^=2|tA4&mQAH|A_D3iubhP14r@F5d6Jx{6jh3yas$&IP=`6My*}-(7^Ct;HXY;7`Z#qk24xg=aGHLJ^+fh;NYKA2s3Mj^Ptu z;6FaYZyd)j?8Ljal__{%2i~$Cx1{2A8TgJoyfz)LUW&gh#MdBr zz6W0HgFm=||Fs`)%Exb=#T!=P>wWQS2k|@?ygmzG&BNPD@b*pkCnxbDFZ^&h{=q!_ zWF?+%5B%{b_%}Tk z)ktHy2%RxlI5%?6ZY$l%)y35jfZdMF$LOJQuo`5!xq7<<0wEFe!~iNDmRQ*CZa)6) z0GWrehsCg!=jkR4(xXzbtX4ETpjXdtu+U&WRP|3YXlu_B)iZZ=0#*{4B6KTmiGmnj zsbV4N=yD-QamiN_E; zVH?&r%TH4=`CvaO@re)|&d6egk9{2n%lVPd7of}(SV4M46aL@?LE0h(9W?Jl_KBI@ z-F~7hZ1jBTPv3t2$>t>FO^_-WY)duQCv|z9ndY=~Svu6Hr3d(F`3bw!v{nFdSgB1Q6VHd-c*2v7ZF{IUDRuWvJx*p|Z5ICc0 zU9HLoXRA#bkw5at2*g0eOp5TG8Vz>Xt$RXaKySuDSWD^f5vK87d0?b!)&Y(Lklp>S zy#DM5<`3iSo(CJ-I@{Z&N{aBfpEr;fm66DjO4mp=mt$?+3QEF$}ybSEVM3Iy1aWU;v3!lv8_ z(94N*wM%9t-?HD>a)R0~i6wDstS54=)@v(hfU8`dA#{$G9B$~1a-x=s!+qXe-}adL zfw5czHyZi?SlZ<6qtVKl=Ag{T4Z}~F(9YXfkNsPQ@_9(Jvt}nU(1P%gG6{=T*D_4H zn9}F@?Z8zHS44KwRKPu$dlVUtDAhh|DGz6p5;U_!Mg36vcSM{Bsf%UAQ2x(jrxz`8 zB%COz^WwIdX}PIID+nhjG)fESrRFcBwPUk0naeSL`XQ$_fWfywA(`&(g#Z$JC>EkQ z6gkN(T#wAR*ZKjDt}g2UWm;r$vPClAgPG$9Kz;?-+Q^l0!Q1GHuV(4vQWdwGVL<_8 zPX&a>l1QX#Fc5r!U4>x^n*#)DfSEC}dpgxAxf2ye!hD+mRtG%>U1&-X0oSYC+0K*m zHxSc!jMY7{(a^UjGfH(qw#?8^hvgyflU+}xDtI$L3>12&>>hT%nACJwk=+BZFp4ID zmQ{AZU?I0$4A`EMh^8=g7a~)#NW;@(_tv^M8aqAe9L={>Db>Ol0_knF>pMtuIYQI& zbKG3B_O$~HMdBK4mzz&+8$g$Aqf+b~r~txrbMXXdEboOp%i<7w2M;k2q*6x%OV%$7 zpKsxF6T>`a15nap%=3$I?l#GzFkgL0@!V{Th>gba_z#GoM|{jJ4)N-#ZU<&1XBmSCl1mtY_wwt8L-wWD7pAUqKed7V8ni;XY6EJobQXbvd z6@TvgPWc-pNHV*SW~rL#loGVfjCeUM@&ucW{0)0@5Dbwrwk<9cW3&<{)!S|K%p!GC zH9KRzvH$=boEDS-w9J*O*C$?@?HrRx1~z6n6$0}&-CDY_8cAN~7_uCIq$j}GRqKmm zVGF!w-OP)+xaYB=W+V#ZwLQOvS=Ci?m3YWNCV@mc@`o{bMGUOUS42fS8LN2yMUOj` z6lE-69TTs?ymO8-#T0~ zQDyd;Lwlc$^#C6Nl>A^?R<8q+FngF>ocpZh%p91MFjVS)v=tPcy+7Sa?-NhJHyJg^ z#>P@z=(#qq-i+9<&9#G?jI_@a%o{^8UvT87{IPi|D{P7@X##&WXU#HrM6hciM%{o1H zt*XLA8$$p^S#Ps})Rj@qOW@5G$E@?en5q8{5g`Gh-n?9Jj-fq<6ksF?Zky2=@x%o&X) za6X4=UkiZLLZW`qU<_2W+ts3*)viiQ)M9}QfE+n<;vgif)Wj{gOq1U~`Ed z5Y*+J>S&RRlLVm{y8$Y3_4dy^RE_Y)>3W6tJSN(BY0qOb&Ca7;y{cgwMoMS73+3Rlc2M$#Yn%LG zav37dp!h04w|xsl=-EmUC2nB1#Upj=i-QwYOHkBN7dK`*2O#@;ETML2ZbyaoI|jyY z7$TeP7!RC%t1))tHl&_JKQ$P;}FL2m^fs`BwgR0OTse zLO?(g=d@_1g)Ox~0cfLga~G1BqDo+%tb{_vVkrzr=ToFW^om6ZZb26LEinTVjYF*a zrJPQ}=e9(jkx=UK+zLsC_59@!UwpL1JTtoo5@MzwF`C7(6c8kCnU3Eo)afkBvuOT!DJsD{rvo!J<}{! zgNR;J$%_sO-DdLTI!0?j=^C09K`?07%oz|6tXP{n!y+PRumY}v3xG3Y(^ohgt>R6| z$TvFk0Nax*;xARpJ|uJ? z&vvr9xuuByQG45}A>DU#>(1RTw9F1ySJV>eSj=r%R{^!Rq}VO34CCAXbEk2`%@=M{g(h! zX{#8*+-1NxuSEL{IrC4pm*{EuDFRCQbZXEtFTJr70@hTbi+x4gOyq(JQ;vydoka3v`ibJezt624W}n(xkYxBFro!xj+t-ADrpv^ zU;03|-2I)9Cl*LDphtXXy&#b2a{12&luT~&9`~`(Z1X`iYcAhCGdB0q%5pgHAau^ZUy-{8F?>{UJ)>(^&{meh#`Qh=j9Iv+D>?~ z?vWE&^|mGtegG0FUgZcF(?WDEJ?#|~5z})HX~2NN8Ys}GzNF${!?FwsY_~|fX?79O z+?B7JyBU0=<|YCK)l|WuWLmw60N|A)bylbiAn%f5G^&EzSREWnDD6+O0ieLRFgvj& zsuKoK8?gjPBA)yXd#Yu-#B>ZfwsFuaV{aw0Q+h?W#;(MXUjs=V>X5~PCrxHhB$GWg zNXTTiS#Fn`*DdeaHjy&R%~b7g>{Ds&VrP@Avz7$KCwxNL$af!JH-tj%#)IxH>7rI$j*GvS_I4pw>Czy}#N+hil4dR;%&s zkq76B$&W&4n=*DAcLL0uM*Ksl(B zZJa?JBHHJHUKaImj{yo6i3W^QCUk|JhnG@rIw1~*-yb=?uPRD}Z-){dXAL&^JFXSi zZf@T#WW`a=>S9kRWKKay>^@%S=5o_p-;CU0` z(hlF{a+dVcagwIo&N4eSF#?Plv!$krBdp#nWATmqGlWJ~i49b91jsM#Y0K-GwSo&9 zG~>m8OD3`Cu^)_1t!&me9Wo+8Ae#|%EHFV@eFPmfpZpBS$x81`>42=Y4& zLuwOjC155CClo&4Oay332E>}0r)e(g(B@vEXzu9YQ@hO|0##1Zd?{T+^&K=G7JqIC z-5AZ~&NBb-q9Vx|ceZs_j}<@K+2&}w>Vol|kCzKb<4xy#RvPs7bM_(}3V2f|kmlY` z8NNrrYyfuyBw#$AEP3akxHN@+-z%Kv_B$;tt#`RAxLM!W;5AaLxz|ec4)o~8wm;FxkO-|aF@BeUCS`U2laXOa zL;2PwvGmj=41hL^8NbS~FCVOicxNx@rf$xr4uM2ypuJNtW=L*hBOfpkGDgN?zk-5$ z-(P-Vhzi65kHUn^m7PMSU*b+H*w-v5wjRHE|JwM1D~2eQlA1jMk{L6+!q=bpW`LI~ zP`S(<+Go3q!F4ZqS9_HX%$oPy1@IRoHal%#MSw3*dm9p5J5rY2m%7b={)cjw%HGa- z?!5a*`&hrS*`>j`v*+LvD^?ZYsaEA&zsaxAF(qTIwYEjAcA{s*DQJi4jW+w&b0wKV z5>3w)IE6GlR}336GKutCeCPyHFVKMzM#Ny9CBid#yEr*me8OmN)znx)@{c|xhHBJ! z%{&v`5Vv_oM#j^J|4#DyEB2yszCpgt699{LfCFq+9+(>7akW zfogy29EJ@K{N1LjS$x1kzeGI8I{@~j3k1%YPs)GA(M{r9|203|{pLdiPG9rcZ!djk zKrg*8P2<}Q%Q9_NuyG*N6qcj1@8`cXN$|VoB~$(!IRN;JHr5S#Cbu!zKS&? zO&-|l8Q;hO48g8fK#dzY#IUvWd8bYfCz4BC*ei`}0Qz=J1d?m5CFpiV>v|1r@SAV1 z>4E2%YH426l;ZP>MVM zdc@t)Zq{Rt@Ez|v^-lZa8zNjk z8fHHFG`1IwyWl2s{|+PVE3_r3YtL~brj=jJ5)QV-EP zXKrX;$L2P11HHTQHaiQ`Dx>Hg&E8ziMU~pawp^DvJt64mU=Z3k0+c_qLwM z+HSQuv&P}RV;iE?0mPl+*A8!fDEwa(Iv>g=dbxXt3C&tKhZSlPT_T%B-jR`WXH2}P z7|cWaasZ9}dymQ2 zl;Vv*VU21pCk}3ND;uj7M#FZH+&_Qpad`{%jz>g}HA-7&fJMOr>|`cnsuB;#T6@0T zWlPcfi^xL8h+i(%RW>GComR)Q>%6!ten-)tsN_GSXE#8LdVSClk>$|urE{)X{E>xz zktm%L0Q=%)B0Z=7ke(W}v+7#qY#0BxcNro1`3EM{W$q8_OrnbfkL$8!#X-+5wwa@w z3=P^NDiV*3!4VxjP?uWoG3XDBGj%$1@o6X0SD1ixCo7T#k{E2CC21=_Krzzpe{kmkwR&F8%4=f1IBGTu3r06fJb|oD{MlkLc0TrNzZu z!l=!Js#mRAx$f1^l{qB~#>@CK2_cu@4vj4#%UTge6_49x81p58@NS~^o zFy`s$2oVJ&S7k09oNgeQ`uJxp`N3)WraKOW@eO-bD{wsMg~T<8^F+cD&^(tH)*whkvv9hJGh7 z=QK`|*)AxnCwBaf)`KUQ)>%>q#o4{qGe;)3b)P?TX#Q=)w0vS$Z|3a=3Kq?uUbKiQ zYqe~M^tPQo_k7eWzHDL5jf`br;AwX6m1^07xhoe>zgU&cFFZ{=-Yrn@cChM8qp$m- zgaw(?S?V?*v8n&^_g9)k*u}nc0&SGm5vEdY6>76X-autGlc6T@PRe~jfx;k5Hl~Y8 zYm1n=)fT0!al?L{fHmSauT7=9RTe=dmkm*XxZ{?pkp`J&?79QsZ#R+FRnY4xv~xk; zp|)%rg#K0Nj3f(9z@&&Q%TI2l=2azCy>;QN9aWR6Egrt%taf&Ru#+oIE7X%FNyGe2XiOJ~^(EEihIMOWvOkrM&PH^?tlG>3DJ#_1HXGXkfHV969wl3h;rJ7JHeh-gNTvtor)e7uAp zvNv3so6GXzwJDWRF*Ys@{=+@J5eley06d`tAUA%3_qWgc#sst>54GW;?xsz&=w##8 zlJV$W-VXrH7zMa~Do(WYZrF>w^g)trpS`$U$iOT7D!w>xrT`cKdxqE`{ze+F!n`&Jt)3a9XdSEd0L4vg9{RkWc?l< zG5=(g#%*9S6MvXAqKK6u%6Y)1rLQbJY*?0v6!pqj5Ifv|HG!&uQ0sd{ESGC38K|uC|6Kk zGB-S~5wx57+M{%Cq*r5bx~sR( diff --git a/deployed/regularlabs/media/modals/index.html b/deployed/regularlabs/media/modals/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/regularlabs/media/modals/index.html @@ -0,0 +1 @@ + diff --git a/deployed/regularlabs/media/modals/js/index.html b/deployed/regularlabs/media/modals/js/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/regularlabs/media/modals/js/index.html @@ -0,0 +1 @@ + diff --git a/deployed/regularlabs/media/modals/js/jquery.colorbox-min.js b/deployed/regularlabs/media/modals/js/jquery.colorbox-min.js new file mode 100644 index 00000000..a9536c30 --- /dev/null +++ b/deployed/regularlabs/media/modals/js/jquery.colorbox-min.js @@ -0,0 +1,6 @@ +/*! + Colorbox 1.6.4 + license: MIT + http://www.jacklmoore.com/colorbox + */ +(function(t,e,i){function n(i,n,o){var r=e.createElement(i);return n&&(r.id=Z+n),o&&(r.style.cssText=o),t(r)}function o(){return i.innerHeight?i.innerHeight:t(i).height()}function r(e,i){i!==Object(i)&&(i={}),this.cache={},this.el=e,this.value=function(e){var n;return void 0===this.cache[e]&&(n=t(this.el).attr("data-cbox-"+e),void 0!==n?this.cache[e]=n:void 0!==i[e]?this.cache[e]=i[e]:void 0!==X[e]&&(this.cache[e]=X[e])),this.cache[e]},this.get=function(e){var i=this.value(e);return t.isFunction(i)?i.call(this.el,this):i}}function h(t){var e=W.length,i=(A+t)%e;return 0>i?e+i:i}function a(t,e){return Math.round((/%/.test(t)?("x"===e?E.width():o())/100:1)*parseInt(t,10))}function s(t,e){return t.get("photo")||t.get("photoRegex").test(e)}function l(t,e){return t.get("retinaUrl")&&i.devicePixelRatio>1?e.replace(t.get("photoRegex"),t.get("retinaSuffix")):e}function d(t){"contains"in x[0]&&!x[0].contains(t.target)&&t.target!==v[0]&&(t.stopPropagation(),x.focus())}function c(t){c.str!==t&&(x.add(v).removeClass(c.str).addClass(t),c.str=t)}function g(e){A=0,e&&e!==!1&&"nofollow"!==e?(W=t("."+te).filter(function(){var i=t.data(this,Y),n=new r(this,i);return n.get("rel")===e}),A=W.index(_.el),-1===A&&(W=W.add(_.el),A=W.length-1)):W=t(_.el)}function u(i){t(e).trigger(i),ae.triggerHandler(i)}function f(i){var o;if(!G){if(o=t(i).data(Y),_=new r(i,o),g(_.get("rel")),!U){U=$=!0,c(_.get("className")),x.css({visibility:"hidden",display:"block",opacity:""}),I=n(se,"LoadedContent","width:0; height:0; overflow:hidden; visibility:hidden"),b.css({width:"",height:""}).append(I),j=T.height()+k.height()+b.outerHeight(!0)-b.height(),D=C.width()+H.width()+b.outerWidth(!0)-b.width(),N=I.outerHeight(!0),z=I.outerWidth(!0);var h=a(_.get("initialWidth"),"x"),s=a(_.get("initialHeight"),"y"),l=_.get("maxWidth"),f=_.get("maxHeight");_.w=Math.max((l!==!1?Math.min(h,a(l,"x")):h)-z-D,0),_.h=Math.max((f!==!1?Math.min(s,a(f,"y")):s)-N-j,0),I.css({width:"",height:_.h}),J.position(),u(ee),_.get("onOpen"),O.add(F).hide(),x.focus(),_.get("trapFocus")&&e.addEventListener&&(e.addEventListener("focus",d,!0),ae.one(re,function(){e.removeEventListener("focus",d,!0)})),_.get("returnFocus")&&ae.one(re,function(){t(_.el).focus()})}var p=parseFloat(_.get("opacity"));v.css({opacity:p===p?p:"",cursor:_.get("overlayClose")?"pointer":"",visibility:"visible"}).show(),_.get("closeButton")?B.html(_.get("close")).appendTo(b):B.appendTo("
"),w()}}function p(){x||(V=!1,E=t(i),x=n(se).attr({id:Y,"class":t.support.opacity===!1?Z+"IE":"",role:"dialog",tabindex:"-1"}).hide(),v=n(se,"Overlay").hide(),L=t([n(se,"LoadingOverlay")[0],n(se,"LoadingGraphic")[0]]),y=n(se,"Wrapper"),b=n(se,"Content").append(F=n(se,"Title"),R=n(se,"Current"),P=t(' +
+
+ +
+ + isClient('administrator') && JFactory::getUser()->authorise('core.admin', 1)) : ?> +
+ +
+ +
+
+
+ diff --git a/deployed/regularlabs/plugins/editors-xtd/modals/modals.php b/deployed/regularlabs/plugins/editors-xtd/modals/modals.php new file mode 100644 index 00000000..f265ef44 --- /dev/null +++ b/deployed/regularlabs/plugins/editors-xtd/modals/modals.php @@ -0,0 +1,28 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +/** + * Button Plugin that places Editor Buttons + */ +class PlgButtonModals + extends \RegularLabs\Library\EditorButton +{ + var $folder = __DIR__; +} diff --git a/deployed/regularlabs/plugins/editors-xtd/modals/modals.xml b/deployed/regularlabs/plugins/editors-xtd/modals/modals.xml new file mode 100644 index 00000000..e30ab8ba --- /dev/null +++ b/deployed/regularlabs/plugins/editors-xtd/modals/modals.xml @@ -0,0 +1,47 @@ + + + plg_editors-xtd_modals + PLG_EDITORS-XTD_MODALS_DESC + 9.13.0 + August 2018 + Regular Labs (Peter van Westen) + info@regularlabs.com + https://www.regularlabs.com + Copyright © 2018 Regular Labs - All Rights Reserved + http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + + script.install.php + + + modals.php + fields.xml + helper.php + popup.php + popup.tmpl.php + script.install.helper.php + fields + language + layouts + + + + +
+ + + + + + + + +
+
+
+
diff --git a/deployed/regularlabs/plugins/editors-xtd/modals/popup.php b/deployed/regularlabs/plugins/editors-xtd/modals/popup.php new file mode 100644 index 00000000..3538d3f1 --- /dev/null +++ b/deployed/regularlabs/plugins/editors-xtd/modals/popup.php @@ -0,0 +1,50 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Plugin\EditorButton\Modals\Popup; + +defined('_JEXEC') or die; + +use JFactory; +use JHtml; +use RegularLabs\Library\Document as RL_Document; +use RegularLabs\Library\RegEx as RL_RegEx; + +class Popup + extends \RegularLabs\Library\EditorButtonPopup +{ + var $require_core_auth = false; + + public function loadScripts() + { + // Tag character start and end + list($tag_start, $tag_end) = explode('.', $this->params->tag_characters); + + JHtml::_('behavior.core'); + + $script = " + var modals_tag = '" . RL_RegEx::replace('[^a-z0-9-_]', '', $this->params->tag) . "'; + var modals_tag_characters = ['" . $tag_start . "', '" . $tag_end . "']; + var modals_editorname = '" . JFactory::getApplication()->input->getString('name', 'text') . "'; + "; + RL_Document::scriptDeclaration($script); + + RL_Document::script('modals/popup.min.js', '9.13.0'); + } + + public function loadStyles() + { + RL_Document::style('modals/popup.min.css', '9.13.0'); + } +} + +$class = new Popup('modals'); +$class->render(); diff --git a/deployed/regularlabs/plugins/editors-xtd/modals/popup.tmpl.php b/deployed/regularlabs/plugins/editors-xtd/modals/popup.tmpl.php new file mode 100644 index 00000000..a60a073c --- /dev/null +++ b/deployed/regularlabs/plugins/editors-xtd/modals/popup.tmpl.php @@ -0,0 +1,78 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +$xmlfile = __DIR__ . '/fields.xml'; + +$form = new JForm('modal'); +$form->loadFile($xmlfile, 1, '//config'); + +?> +
+ + + + +
+
+ + +
+ renderFieldset('text'); ?> +
+ +
+ +
+ ['RL_URL', 'link'], + 'image' => ['RL_IMAGE', 'image'], + 'gallery' => ['RL_GALLERY', 'images'], + 'video' => ['RL_VIDEO', 'video-2'], + 'article' => ['RL_ARTICLE', 'file-2'], + 'content' => ['RL_CONTENT', 'paragraph-justify'], + ]; + + echo JHtml::_('bootstrap.startTabSet', 'myTab', ['active' => 'tab-url']); + + foreach ($tabs as $id => $data) + { + echo JHtml::_('bootstrap.addTab', 'myTab', 'tab-' . $id, + ' ' . JText::_($data[0]) + ); + echo $form->renderFieldset($id); + echo JHtml::_('bootstrap.endTab'); + } + + echo JHtml::_('bootstrap.endTabSet'); + + ?> +
+ +
+ renderFieldset('settings'); ?> +
+
+ +
+ ', + '' + ); + ?> +
+ +
+
diff --git a/deployed/regularlabs/plugins/editors-xtd/modals/script.install.helper.php b/deployed/regularlabs/plugins/editors-xtd/modals/script.install.helper.php new file mode 100644 index 00000000..96bffe13 --- /dev/null +++ b/deployed/regularlabs/plugins/editors-xtd/modals/script.install.helper.php @@ -0,0 +1,852 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +class PlgEditorsXtdModalsInstallerScriptHelper +{ + public $name = ''; + public $alias = ''; + public $extname = ''; + public $extension_type = ''; + public $plugin_folder = 'system'; + public $module_position = 'status'; + public $client_id = 1; + public $install_type = 'install'; + public $show_message = true; + public $db = null; + public $softbreak = null; + + public function __construct(&$params) + { + $this->extname = $this->extname ?: $this->alias; + $this->db = JFactory::getDbo(); + } + + public function preflight($route, JAdapterInstance $adapter) + { + if ( ! in_array($route, ['install', 'update'])) + { + return true; + } + + JFactory::getLanguage()->load('plg_system_regularlabsinstaller', JPATH_PLUGINS . '/system/regularlabsinstaller'); + + if ($this->show_message && $this->isInstalled()) + { + $this->install_type = 'update'; + } + + if ($this->onBeforeInstall($route) === false) + { + return false; + } + + return true; + } + + public function postflight($route, JAdapterInstance $adapter) + { + $this->removeGlobalLanguageFiles(); + $this->removeUnusedLanguageFiles(); + + JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); + + if ( ! in_array($route, ['install', 'update'])) + { + return true; + } + + $this->fixExtensionNames(); + $this->updateUpdateSites(); + $this->removeAdminCache(); + + if ($this->onAfterInstall($route) === false) + { + return false; + } + + if ($route == 'install') + { + $this->publishExtension(); + } + + if ($this->show_message) + { + $this->addInstalledMessage(); + } + + JFactory::getCache()->clean('com_plugins'); + JFactory::getCache()->clean('_system'); + + return true; + } + + public function isInstalled() + { + if ( ! is_file($this->getInstalledXMLFile())) + { + return false; + } + + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('extension_id')) + ->from('#__extensions') + ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); + $this->db->setQuery($query, 0, 1); + $result = $this->db->loadResult(); + + return empty($result) ? false : true; + } + + public function getMainFolder() + { + switch ($this->extension_type) + { + case 'plugin' : + return JPATH_PLUGINS . '/' . $this->plugin_folder . '/' . $this->extname; + + case 'component' : + return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; + + case 'module' : + return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; + + case 'library' : + return JPATH_SITE . '/libraries/' . $this->extname; + } + } + + public function getInstalledXMLFile() + { + return $this->getXMLFile($this->getMainFolder()); + } + + public function getCurrentXMLFile() + { + return $this->getXMLFile(__DIR__); + } + + public function getXMLFile($folder) + { + switch ($this->extension_type) + { + case 'module' : + return $folder . '/mod_' . $this->extname . '.xml'; + + default : + return $folder . '/' . $this->extname . '.xml'; + } + } + + public function uninstallExtension($extname, $type = 'plugin', $folder = 'system', $show_message = true) + { + if (empty($extname)) + { + return; + } + + $folders = []; + + switch ($type) + { + case 'plugin'; + $folders[] = JPATH_PLUGINS . '/' . $folder . '/' . $extname; + break; + + case 'component': + $folders[] = JPATH_ADMINISTRATOR . '/components/com_' . $extname; + $folders[] = JPATH_SITE . '/components/com_' . $extname; + break; + + case 'module': + $folders[] = JPATH_ADMINISTRATOR . '/modules/mod_' . $extname; + $folders[] = JPATH_SITE . '/modules/mod_' . $extname; + break; + } + + if ( ! $this->foldersExist($folders)) + { + return; + } + + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('extension_id')) + ->from('#__extensions') + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName($type, $extname))) + ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($type)); + + if ($type == 'plugin') + { + $query->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($folder)); + } + + $this->db->setQuery($query); + $ids = $this->db->loadColumn(); + + if (empty($ids)) + { + foreach ($folders as $folder) + { + JFolder::delete($folder); + } + + return; + } + + $ignore_ids = JFactory::getApplication()->getUserState('rl_ignore_uninstall_ids', []); + + if (JFactory::getApplication()->input->get('option') == 'com_installer' && JFactory::getApplication()->input->get('task') == 'remove') + { + // Don't attempt to uninstall extensions that are already selected to get uninstalled by them selves + $ignore_ids = array_merge($ignore_ids, JFactory::getApplication()->input->get('cid', [], 'array')); + JFactory::getApplication()->input->set('cid', array_merge($ignore_ids, $ids)); + } + + $ids = array_diff($ids, $ignore_ids); + + if (empty($ids)) + { + return; + } + + $ignore_ids = array_merge($ignore_ids, $ids); + JFactory::getApplication()->setUserState('rl_ignore_uninstall_ids', $ignore_ids); + + foreach ($ids as $id) + { + $tmpInstaller = new JInstaller; + $tmpInstaller->uninstall($type, $id); + } + + if ($show_message) + { + JFactory::getApplication()->enqueueMessage( + JText::sprintf( + 'COM_INSTALLER_UNINSTALL_SUCCESS', + JText::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($type)) + ) + ); + } + } + + public function foldersExist($folders = []) + { + foreach ($folders as $folder) + { + if (is_dir($folder)) + { + return true; + } + } + + return false; + } + + public function uninstallPlugin($extname, $folder = 'system', $show_message = true) + { + $this->uninstallExtension($extname, 'plugin', $folder, $show_message); + } + + public function uninstallComponent($extname, $show_message = true) + { + $this->uninstallExtension($extname, 'component', null, $show_message); + } + + public function uninstallModule($extname, $show_message = true) + { + $this->uninstallExtension($extname, 'module', null, $show_message); + } + + public function publishExtension() + { + switch ($this->extension_type) + { + case 'plugin' : + $this->publishPlugin(); + + case 'module' : + $this->publishModule(); + } + } + + public function publishPlugin() + { + $query = $this->db->getQuery(true) + ->update('#__extensions') + ->set($this->db->quoteName('enabled') . ' = 1') + ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) + ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); + $this->db->setQuery($query); + $this->db->execute(); + } + + public function publishModule() + { + // Get module id + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('id')) + ->from('#__modules') + ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) + ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + if ( ! $id) + { + return; + } + + // check if module is already in the modules_menu table (meaning is is already saved) + $query->clear() + ->select($this->db->quoteName('moduleid')) + ->from('#__modules_menu') + ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); + $this->db->setQuery($query, 0, 1); + $exists = $this->db->loadResult(); + + if ($exists) + { + return; + } + + // Get highest ordering number in position + $query->clear() + ->select($this->db->quoteName('ordering')) + ->from('#__modules') + ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) + ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) + ->order('ordering DESC'); + $this->db->setQuery($query, 0, 1); + $ordering = $this->db->loadResult(); + $ordering++; + + // publish module and set ordering number + $query->clear() + ->update('#__modules') + ->set($this->db->quoteName('published') . ' = 1') + ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) + ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) + ->where($this->db->quoteName('id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + + // add module to the modules_menu table + $query->clear() + ->insert('#__modules_menu') + ->columns([$this->db->quoteName('moduleid'), $this->db->quoteName('menuid')]) + ->values((int) $id . ', 0'); + $this->db->setQuery($query); + $this->db->execute(); + } + + public function addInstalledMessage() + { + JFactory::getApplication()->enqueueMessage( + JText::sprintf( + JText::_($this->install_type == 'update' ? 'RLI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'RLI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), + '' . JText::_($this->name) . '', + '' . $this->getVersion() . '', + $this->getFullType() + ) + ); + } + + public function getPrefix() + { + switch ($this->extension_type) + { + case 'plugin'; + return JText::_('plg_' . strtolower($this->plugin_folder)); + + case 'component': + return JText::_('com'); + + case 'module': + return JText::_('mod'); + + case 'library': + return JText::_('lib'); + + default: + return $this->extension_type; + } + } + + public function getElementName($type = null, $extname = null) + { + $type = is_null($type) ? $this->extension_type : $type; + $extname = is_null($extname) ? $this->extname : $extname; + + switch ($type) + { + case 'component' : + return 'com_' . $extname; + + case 'module' : + return 'mod_' . $extname; + + case 'plugin' : + default: + return $extname; + } + } + + public function getFullType() + { + return JText::_('RLI_' . strtoupper($this->getPrefix())); + } + + public function getVersion($file = '') + { + $file = $file ?: $this->getCurrentXMLFile(); + + if ( ! is_file($file)) + { + return ''; + } + + $xml = JApplicationHelper::parseXMLInstallFile($file); + + if ( ! $xml || ! isset($xml['version'])) + { + return ''; + } + + return $xml['version']; + } + + public function isNewer() + { + if ( ! $installed_version = $this->getVersion($this->getInstalledXMLFile())) + { + return true; + } + + $package_version = $this->getVersion(); + + return version_compare($installed_version, $package_version, '<='); + } + + public function canInstall() + { + // The extension is not installed yet + if ( ! $installed_version = $this->getVersion($this->getInstalledXMLFile())) + { + return true; + } + + // The free version is installed. So any version is ok to install + if (strpos($installed_version, 'PRO') === false) + { + return true; + } + + // Current package is a pro version, so all good + if (strpos($this->getVersion(), 'PRO') !== false) + { + return true; + } + + JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); + + JFactory::getApplication()->enqueueMessage(JText::_('RLI_ERROR_PRO_TO_FREE'), 'error'); + + JFactory::getApplication()->enqueueMessage( + html_entity_decode( + JText::sprintf( + 'RLI_ERROR_UNINSTALL_FIRST', + '', + '', + JText::_($this->name) + ) + ), 'error' + ); + + return false; + } + + /* + * Fixes incorrectly formed versions because of issues in old packager + */ + public function fixFileVersions($file) + { + if (is_array($file)) + { + foreach ($file as $f) + { + self::fixFileVersions($f); + } + + return; + } + + if ( ! is_string($file) || ! is_file($file)) + { + return; + } + + $contents = file_get_contents($file); + + if ( + strpos($contents, 'FREEFREE') === false + && strpos($contents, 'FREEPRO') === false + && strpos($contents, 'PROFREE') === false + && strpos($contents, 'PROPRO') === false + ) + { + return; + } + + $contents = str_replace( + ['FREEFREE', 'FREEPRO', 'PROFREE', 'PROPRO'], + ['FREE', 'PRO', 'FREE', 'PRO'], + $contents + ); + + JFile::write($file, $contents); + } + + public function onBeforeInstall($route) + { + if ( ! $this->canInstall()) + { + return false; + } + + return true; + } + + public function onAfterInstall($route) + { + } + + public function delete($files = []) + { + foreach ($files as $file) + { + if (is_dir($file)) + { + JFolder::delete($file); + } + + if (is_file($file)) + { + JFile::delete($file); + } + } + } + + public function fixAssetsRules($rules = '{"core.admin":[],"core.manage":[]}') + { + // replace default rules value {} with the correct initial value + $query = $this->db->getQuery(true) + ->update($this->db->quoteName('#__assets')) + ->set($this->db->quoteName('rules') . ' = ' . $this->db->quote($rules)) + ->where($this->db->quoteName('title') . ' = ' . $this->db->quote('com_' . $this->extname)) + ->where($this->db->quoteName('rules') . ' = ' . $this->db->quote('{}')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function fixExtensionNames() + { + switch ($this->extension_type) + { + case 'module' : + $this->fixModuleNames(); + } + } + + private function fixModuleNames() + { + // Get module id + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('id')) + ->from('#__modules') + ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) + ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); + $this->db->setQuery($query, 0, 1); + $module_id = $this->db->loadResult(); + + if (empty($module_id)) + { + return; + } + + $title = 'Regular Labs - ' . JText::_($this->name); + + $query->clear() + ->update('#__modules') + ->set($this->db->quoteName('title') . ' = ' . $this->db->quote($title)) + ->where($this->db->quoteName('id') . ' = ' . (int) $module_id) + ->where($this->db->quoteName('title') . ' LIKE ' . $this->db->quote('NoNumber%')); + $this->db->setQuery($query); + $this->db->execute(); + + // Fix module assets + + // Get asset id + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('id')) + ->from('#__assets') + ->where($this->db->quoteName('name') . ' = ' . $this->db->quote('com_modules.module.' . (int) $module_id)) + ->where($this->db->quoteName('title') . ' LIKE ' . $this->db->quote('NoNumber%')); + $this->db->setQuery($query, 0, 1); + $asset_id = $this->db->loadResult(); + + if (empty($asset_id)) + { + return; + } + + $query->clear() + ->update('#__assets') + ->set($this->db->quoteName('title') . ' = ' . $this->db->quote($title)) + ->where($this->db->quoteName('id') . ' = ' . (int) $asset_id); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function updateUpdateSites() + { + $this->removeOldUpdateSites(); + $this->updateNamesInUpdateSites(); + $this->updateHttptoHttpsInUpdateSites(); + $this->removeDuplicateUpdateSite(); + $this->updateDownloadKey(); + } + + private function removeOldUpdateSites() + { + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('nonumber.nl%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + if ( ! $id) + { + return; + } + + $query->clear() + ->delete('#__update_sites') + ->where($this->db->quoteName('update_site_id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + + $query->clear() + ->delete('#__update_sites_extensions') + ->where($this->db->quoteName('update_site_id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function updateNamesInUpdateSites() + { + $name = JText::_($this->name); + if ($this->alias != 'extensionmanager') + { + $name = 'Regular Labs - ' . $name; + } + + $query = $this->db->getQuery(true) + ->update('#__update_sites') + ->set($this->db->quoteName('name') . ' = ' . $this->db->quote($name)) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function updateHttptoHttpsInUpdateSites() + { + $query = $this->db->getQuery(true) + ->update('#__update_sites') + ->set($this->db->quoteName('location') . ' = REPLACE(' + . $this->db->quoteName('location') . ', ' + . $this->db->quote('http://') . ', ' + . $this->db->quote('https://') + . ')') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('http://download.regularlabs.com%')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function removeDuplicateUpdateSite() + { + // First check to see if there is a pro entry + + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')) + ->where($this->db->quoteName('location') . ' NOT LIKE ' . $this->db->quote('%pro=1%')); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + // Otherwise just get the first match + if ( ! $id) + { + $query->clear() + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + // Remove pro=1 from the found update site + $query->clear() + ->update('#__update_sites') + ->set($this->db->quoteName('location') + . ' = replace(' . $this->db->quoteName('location') . ', ' . $this->db->quote('&pro=1') . ', ' . $this->db->quote('') . ')') + ->where($this->db->quoteName('update_site_id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + } + + if ( ! $id) + { + return; + } + + $query->clear() + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')) + ->where($this->db->quoteName('update_site_id') . ' != ' . $id); + $this->db->setQuery($query); + $ids = $this->db->loadColumn(); + + if (empty($ids)) + { + return; + } + + $query->clear() + ->delete('#__update_sites') + ->where($this->db->quoteName('update_site_id') . ' IN (' . implode(',', $ids) . ')'); + $this->db->setQuery($query); + $this->db->execute(); + + $query->clear() + ->delete('#__update_sites_extensions') + ->where($this->db->quoteName('update_site_id') . ' IN (' . implode(',', $ids) . ')'); + $this->db->setQuery($query); + $this->db->execute(); + } + + // Save the download key from the Regular Labs Extension Manager config to the update sites + private function updateDownloadKey() + { + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('params')) + ->from('#__extensions') + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote('com_regularlabsmanager')); + $this->db->setQuery($query); + $params = $this->db->loadResult(); + + if ( ! $params) + { + return; + } + + $params = json_decode($params); + + if ( ! isset($params->key)) + { + return; + } + + // Add the key on all regularlabs.com urls + $query->clear() + ->update('#__update_sites') + ->set($this->db->quoteName('extra_query') . ' = ' . $this->db->quote('k=' . $params->key)) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function removeAdminCache() + { + $this->delete([JPATH_ADMINISTRATOR . '/cache/regularlabs']); + $this->delete([JPATH_ADMINISTRATOR . '/cache/nonumber']); + } + + private function removeGlobalLanguageFiles() + { + if ($this->extension_type == 'library') + { + return; + } + + $language_files = JFolder::files(JPATH_ADMINISTRATOR . '/language', '\.' . $this->getPrefix() . '_' . $this->extname . '\.', true, true); + + // Remove override files + foreach ($language_files as $i => $language_file) + { + if (strpos($language_file, '/overrides/') === false) + { + continue; + } + + unset($language_files[$i]); + } + + if (empty($language_files)) + { + return; + } + + JFile::delete($language_files); + } + + private function removeUnusedLanguageFiles() + { + if ($this->extension_type == 'library') + { + return; + } + + $installed_languages = array_merge( + JFolder::folders(JPATH_SITE . '/language'), + JFolder::folders(JPATH_ADMINISTRATOR . '/language') + ); + + $languages = array_diff( + JFolder::folders(__DIR__ . '/language'), + $installed_languages + ); + + $delete_languages = []; + + foreach ($languages as $language) + { + $delete_languages[] = $this->getMainFolder() . '/language/' . $language; + } + + if (empty($delete_languages)) + { + return; + } + + // Remove folders + $this->delete($delete_languages); + } +} diff --git a/deployed/regularlabs/plugins/editors-xtd/modals/script.install.php b/deployed/regularlabs/plugins/editors-xtd/modals/script.install.php new file mode 100644 index 00000000..f76795a6 --- /dev/null +++ b/deployed/regularlabs/plugins/editors-xtd/modals/script.install.php @@ -0,0 +1,27 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +require_once __DIR__ . '/script.install.helper.php'; + +class PlgEditorsXtdModalsInstallerScript extends PlgEditorsXtdModalsInstallerScriptHelper +{ + public $name = 'MODALS'; + public $alias = 'modals'; + public $extension_type = 'plugin'; + public $plugin_folder = 'editors-xtd'; + + public function uninstall($adapter) + { + $this->uninstallPlugin($this->extname, 'system'); + } +} diff --git a/deployed/regularlabs/plugins/editors-xtd/sourcerer/helper.php b/deployed/regularlabs/plugins/editors-xtd/sourcerer/helper.php new file mode 100644 index 00000000..7152343d --- /dev/null +++ b/deployed/regularlabs/plugins/editors-xtd/sourcerer/helper.php @@ -0,0 +1,33 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Object\CMSObject as JObject; + +/** + * Plugin that places the Button + */ +class PlgButtonSourcererHelper + extends \RegularLabs\Library\EditorButtonHelper +{ + /** + * Display the button + * + * @param string $editor_name + * + * @return JObject|null A button object + */ + public function render($editor_name) + { + return $this->renderPopupButton($editor_name); + } +} diff --git a/deployed/regularlabs/plugins/editors-xtd/sourcerer/language/en-GB/en-GB.plg_editors-xtd_sourcerer.ini b/deployed/regularlabs/plugins/editors-xtd/sourcerer/language/en-GB/en-GB.plg_editors-xtd_sourcerer.ini new file mode 100644 index 00000000..3bd04c05 --- /dev/null +++ b/deployed/regularlabs/plugins/editors-xtd/sourcerer/language/en-GB/en-GB.plg_editors-xtd_sourcerer.ini @@ -0,0 +1,19 @@ +;; @package Sourcerer +;; @version 7.4.0 +;; +;; @author Peter van Westen +;; @link http://www.regularlabs.com +;; @copyright Copyright © 2018 Regular Labs All Rights Reserved +;; @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL +;; +;; @translate Want to help with translations? See: https://www.regularlabs.com/translate + +PLG_EDITORS-XTD_SOURCERER="Button - Regular Labs - Sourcerer" +PLG_EDITORS-XTD_SOURCERER_DESC="Sourcerer - place any code in Joomla!" +SOURCERER="Sourcerer" + +CODE="Code" +SOURCERER_DESC="With the Sourcerer editor button you can easily place your code (with Sourcerer tags and styling) into your text." + +SRC_SETTINGS="Please see the [[%1:start link%]]Sourcerer system plugin[[%2:end link%]] for settings." +SRC_THE_SYSTEM_PLUGIN="the Sourcerer system plugin" diff --git a/deployed/regularlabs/plugins/editors-xtd/sourcerer/language/en-GB/en-GB.plg_editors-xtd_sourcerer.sys.ini b/deployed/regularlabs/plugins/editors-xtd/sourcerer/language/en-GB/en-GB.plg_editors-xtd_sourcerer.sys.ini new file mode 100644 index 00000000..6a974aad --- /dev/null +++ b/deployed/regularlabs/plugins/editors-xtd/sourcerer/language/en-GB/en-GB.plg_editors-xtd_sourcerer.sys.ini @@ -0,0 +1,13 @@ +;; @package Sourcerer +;; @version 7.4.0 +;; +;; @author Peter van Westen +;; @link http://www.regularlabs.com +;; @copyright Copyright © 2018 Regular Labs All Rights Reserved +;; @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL +;; +;; @translate Want to help with translations? See: https://www.regularlabs.com/translate + +PLG_EDITORS-XTD_SOURCERER="Button - Regular Labs - Sourcerer" +PLG_EDITORS-XTD_SOURCERER_DESC="Sourcerer - place any code in Joomla!" +SOURCERER="Sourcerer" diff --git a/deployed/regularlabs/plugins/editors-xtd/sourcerer/popup.php b/deployed/regularlabs/plugins/editors-xtd/sourcerer/popup.php new file mode 100644 index 00000000..105d3b0b --- /dev/null +++ b/deployed/regularlabs/plugins/editors-xtd/sourcerer/popup.php @@ -0,0 +1,183 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Access\Exception\NotAllowed as JAccessExceptionNotallowed; +use Joomla\CMS\Editor\Editor as JEditor; +use Joomla\CMS\Factory as JFactory; +use Joomla\CMS\Language\Text as JText; +use Joomla\CMS\Plugin\PluginHelper as JPluginHelper; +use Joomla\CMS\Uri\Uri as JUri; +use RegularLabs\Library\Document as RL_Document; +use RegularLabs\Library\Language as RL_Language; +use RegularLabs\Library\Parameters as RL_Parameters; +use RegularLabs\Library\RegEx as RL_RegEx; + +$user = JFactory::getUser(); +if ($user->get('guest') + || ( + ! $user->authorise('core.edit', 'com_content') + && ! $user->authorise('core.edit.own', 'com_content') + && ! $user->authorise('core.create', 'com_content') + ) +) +{ + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); +} + +$params = RL_Parameters::getInstance()->getPluginParams('sourcerer'); + +if (RL_Document::isClient('site')) +{ + if ( ! $params->enable_frontend) + { + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); + } +} + +(new PlgButtonSourcererPopup($params))->render(); + +class PlgButtonSourcererPopup +{ + var $params = null; + + public function __construct(&$params) + { + $this->params = $params; + } + + public function render() + { + jimport('joomla.filesystem.file'); + + // Load plugin language + RL_Language::load('plg_system_regularlabs'); + RL_Language::load('plg_editors-xtd_sourcerer'); + RL_Language::load('plg_system_sourcerer'); + + RL_Document::loadPopupDependencies(); + + JFactory::getDocument()->addStyleSheet('//code.jquery.com/ui/1.9.2/themes/smoothness/jquery-ui.css'); + JFactory::getDocument()->addScript('//code.jquery.com/ui/1.9.2/jquery-ui.js'); + + // Tag character start and end + list($tag_start, $tag_end) = explode('.', $this->params->tag_characters); + + $editor = JFactory::getApplication()->input->getString('name', 'text'); + // Remove any dangerous character to prevent cross site scripting + $editor = RL_RegEx::replace('[\'\";\s]', '', $editor); + + $script = " + var sourcerer_syntax_word = '" . $this->params->syntax_word . "'; + var sourcerer_tag_characters = ['" . $tag_start . "', '" . $tag_end . "']; + var sourcerer_editorname = '" . $editor . "'; + var sourcerer_default_addsourcetags = " . (int) $this->params->addsourcetags . "; + var sourcerer_root = '" . JUri::root(true) . "'; + "; + RL_Document::scriptDeclaration($script); + + RL_Document::script('sourcerer/script.min.js', '7.4.0'); + RL_Document::style('sourcerer/popup.min.css', '7.4.0'); + + $this->params->code = '



// You can place PHP like this

?>'; + $this->params->code = str_replace(['
', '
'], "\n", $this->params->code); + + echo $this->getHTML(); + } + + function getHTML() + { + $editor_plugin = JPluginHelper::getPlugin('editors', 'codemirror'); + + if (empty($editor_plugin)) + { + JFactory::getApplication()->enqueueMessage(JText::sprintf('SRC_ERROR_CODEMIRROR_DISABLED', '', ''), 'error'); + + return ''; + } + + $editor = JEditor::getInstance('codemirror'); + + ob_start(); + ?> +
+

+ + +

+
+ +
+
+
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ + authorise('core.admin', 1)) : ?> +
+ +
+ +
+
+
+ +
+
+ +
+
+ +
+ display( + 'source', + $this->params->code, + '100%', '100%', 10, 10, 0, null, null, null, + ['syntax' => 'php', 'linenumbers' => 1, 'tabmode' => 'shift'] + ); ?> +
+ + +
+
+ + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +class PlgEditorsXtdSourcererInstallerScriptHelper +{ + public $name = ''; + public $alias = ''; + public $extname = ''; + public $extension_type = ''; + public $plugin_folder = 'system'; + public $module_position = 'status'; + public $client_id = 1; + public $install_type = 'install'; + public $show_message = true; + public $db = null; + public $softbreak = null; + public $installed_version = ''; + + public function __construct(&$params) + { + $this->extname = $this->extname ?: $this->alias; + $this->db = JFactory::getDbo(); + } + + public function preflight($route, JAdapterInstance $adapter) + { + if ( ! in_array($route, ['install', 'update'])) + { + return true; + } + + JFactory::getLanguage()->load('plg_system_regularlabsinstaller', JPATH_PLUGINS . '/system/regularlabsinstaller'); + + $this->installed_version = $this->getVersion($this->getInstalledXMLFile()); + + if ($this->show_message && $this->isInstalled()) + { + $this->install_type = 'update'; + } + + if ($this->onBeforeInstall($route) === false) + { + return false; + } + + return true; + } + + public function postflight($route, JAdapterInstance $adapter) + { + $this->removeGlobalLanguageFiles(); + $this->removeUnusedLanguageFiles(); + + JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); + + if ( ! in_array($route, ['install', 'update'])) + { + return true; + } + + $this->fixExtensionNames(); + $this->updateUpdateSites(); + $this->removeAdminCache(); + + if ($this->onAfterInstall($route) === false) + { + return false; + } + + if ($route == 'install') + { + $this->publishExtension(); + } + + if ($this->show_message) + { + $this->addInstalledMessage(); + } + + JFactory::getCache()->clean('com_plugins'); + JFactory::getCache()->clean('_system'); + + return true; + } + + public function isInstalled() + { + if ( ! is_file($this->getInstalledXMLFile())) + { + return false; + } + + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('extension_id')) + ->from('#__extensions') + ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); + $this->db->setQuery($query, 0, 1); + $result = $this->db->loadResult(); + + return empty($result) ? false : true; + } + + public function getMainFolder() + { + switch ($this->extension_type) + { + case 'plugin' : + return JPATH_PLUGINS . '/' . $this->plugin_folder . '/' . $this->extname; + + case 'component' : + return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; + + case 'module' : + return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; + + case 'library' : + return JPATH_SITE . '/libraries/' . $this->extname; + } + } + + public function getInstalledXMLFile() + { + return $this->getXMLFile($this->getMainFolder()); + } + + public function getCurrentXMLFile() + { + return $this->getXMLFile(__DIR__); + } + + public function getXMLFile($folder) + { + switch ($this->extension_type) + { + case 'module' : + return $folder . '/mod_' . $this->extname . '.xml'; + + default : + return $folder . '/' . $this->extname . '.xml'; + } + } + + public function uninstallExtension($extname, $type = 'plugin', $folder = 'system', $show_message = true) + { + if (empty($extname)) + { + return; + } + + $folders = []; + + switch ($type) + { + case 'plugin'; + $folders[] = JPATH_PLUGINS . '/' . $folder . '/' . $extname; + break; + + case 'component': + $folders[] = JPATH_ADMINISTRATOR . '/components/com_' . $extname; + $folders[] = JPATH_SITE . '/components/com_' . $extname; + break; + + case 'module': + $folders[] = JPATH_ADMINISTRATOR . '/modules/mod_' . $extname; + $folders[] = JPATH_SITE . '/modules/mod_' . $extname; + break; + } + + if ( ! $this->foldersExist($folders)) + { + return; + } + + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('extension_id')) + ->from('#__extensions') + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName($type, $extname))) + ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($type)); + + if ($type == 'plugin') + { + $query->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($folder)); + } + + $this->db->setQuery($query); + $ids = $this->db->loadColumn(); + + if (empty($ids)) + { + foreach ($folders as $folder) + { + JFactory::getApplication()->enqueueMessage('2. Deleting: ' . $folder, 'notice'); + JFolder::delete($folder); + } + + return; + } + + $ignore_ids = JFactory::getApplication()->getUserState('rl_ignore_uninstall_ids', []); + + if (JFactory::getApplication()->input->get('option') == 'com_installer' && JFactory::getApplication()->input->get('task') == 'remove') + { + // Don't attempt to uninstall extensions that are already selected to get uninstalled by them selves + $ignore_ids = array_merge($ignore_ids, JFactory::getApplication()->input->get('cid', [], 'array')); + JFactory::getApplication()->input->set('cid', array_merge($ignore_ids, $ids)); + } + + $ids = array_diff($ids, $ignore_ids); + + if (empty($ids)) + { + return; + } + + $ignore_ids = array_merge($ignore_ids, $ids); + JFactory::getApplication()->setUserState('rl_ignore_uninstall_ids', $ignore_ids); + + foreach ($ids as $id) + { + $tmpInstaller = new JInstaller; + $tmpInstaller->uninstall($type, $id); + } + + if ($show_message) + { + JFactory::getApplication()->enqueueMessage( + JText::sprintf( + 'COM_INSTALLER_UNINSTALL_SUCCESS', + JText::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($type)) + ) + ); + } + } + + public function foldersExist($folders = []) + { + foreach ($folders as $folder) + { + if (is_dir($folder)) + { + return true; + } + } + + return false; + } + + public function uninstallPlugin($extname, $folder = 'system', $show_message = true) + { + $this->uninstallExtension($extname, 'plugin', $folder, $show_message); + } + + public function uninstallComponent($extname, $show_message = true) + { + $this->uninstallExtension($extname, 'component', null, $show_message); + } + + public function uninstallModule($extname, $show_message = true) + { + $this->uninstallExtension($extname, 'module', null, $show_message); + } + + public function publishExtension() + { + switch ($this->extension_type) + { + case 'plugin' : + $this->publishPlugin(); + + case 'module' : + $this->publishModule(); + } + } + + public function publishPlugin() + { + $query = $this->db->getQuery(true) + ->update('#__extensions') + ->set($this->db->quoteName('enabled') . ' = 1') + ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) + ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); + $this->db->setQuery($query); + $this->db->execute(); + } + + public function publishModule() + { + // Get module id + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('id')) + ->from('#__modules') + ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) + ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + if ( ! $id) + { + return; + } + + // check if module is already in the modules_menu table (meaning is is already saved) + $query->clear() + ->select($this->db->quoteName('moduleid')) + ->from('#__modules_menu') + ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); + $this->db->setQuery($query, 0, 1); + $exists = $this->db->loadResult(); + + if ($exists) + { + return; + } + + // Get highest ordering number in position + $query->clear() + ->select($this->db->quoteName('ordering')) + ->from('#__modules') + ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) + ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) + ->order('ordering DESC'); + $this->db->setQuery($query, 0, 1); + $ordering = $this->db->loadResult(); + $ordering++; + + // publish module and set ordering number + $query->clear() + ->update('#__modules') + ->set($this->db->quoteName('published') . ' = 1') + ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) + ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) + ->where($this->db->quoteName('id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + + // add module to the modules_menu table + $query->clear() + ->insert('#__modules_menu') + ->columns([$this->db->quoteName('moduleid'), $this->db->quoteName('menuid')]) + ->values((int) $id . ', 0'); + $this->db->setQuery($query); + $this->db->execute(); + } + + public function addInstalledMessage() + { + JFactory::getApplication()->enqueueMessage( + JText::sprintf( + JText::_($this->install_type == 'update' ? 'RLI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'RLI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), + '' . JText::_($this->name) . '', + '' . $this->getVersion() . '', + $this->getFullType() + ) + ); + } + + public function getPrefix() + { + switch ($this->extension_type) + { + case 'plugin'; + return JText::_('plg_' . strtolower($this->plugin_folder)); + + case 'component': + return JText::_('com'); + + case 'module': + return JText::_('mod'); + + case 'library': + return JText::_('lib'); + + default: + return $this->extension_type; + } + } + + public function getElementName($type = null, $extname = null) + { + $type = is_null($type) ? $this->extension_type : $type; + $extname = is_null($extname) ? $this->extname : $extname; + + switch ($type) + { + case 'component' : + return 'com_' . $extname; + + case 'module' : + return 'mod_' . $extname; + + case 'plugin' : + default: + return $extname; + } + } + + public function getFullType() + { + return JText::_('RLI_' . strtoupper($this->getPrefix())); + } + + public function getVersion($file = '') + { + $file = $file ?: $this->getCurrentXMLFile(); + + if ( ! is_file($file)) + { + return ''; + } + + $xml = JApplicationHelper::parseXMLInstallFile($file); + + if ( ! $xml || ! isset($xml['version'])) + { + return ''; + } + + return $xml['version']; + } + + public function isNewer() + { + if ( ! $this->installed_version) + { + return true; + } + + $package_version = $this->getVersion(); + + return version_compare($this->installed_version, $package_version, '<='); + } + + public function canInstall() + { + // The extension is not installed yet + if ( ! $this->installed_version) + { + return true; + } + + // The free version is installed. So any version is ok to install + if (strpos($this->installed_version, 'PRO') === false) + { + return true; + } + + // Current package is a pro version, so all good + if (strpos($this->getVersion(), 'PRO') !== false) + { + return true; + } + + JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); + + JFactory::getApplication()->enqueueMessage(JText::_('RLI_ERROR_PRO_TO_FREE'), 'error'); + + JFactory::getApplication()->enqueueMessage( + html_entity_decode( + JText::sprintf( + 'RLI_ERROR_UNINSTALL_FIRST', + '', + '', + JText::_($this->name) + ) + ), 'error' + ); + + return false; + } + + /* + * Fixes incorrectly formed versions because of issues in old packager + */ + public function fixFileVersions($file) + { + if (is_array($file)) + { + foreach ($file as $f) + { + self::fixFileVersions($f); + } + + return; + } + + if ( ! is_string($file) || ! is_file($file)) + { + return; + } + + $contents = file_get_contents($file); + + if ( + strpos($contents, 'FREEFREE') === false + && strpos($contents, 'FREEPRO') === false + && strpos($contents, 'PROFREE') === false + && strpos($contents, 'PROPRO') === false + ) + { + return; + } + + $contents = str_replace( + ['FREEFREE', 'FREEPRO', 'PROFREE', 'PROPRO'], + ['FREE', 'PRO', 'FREE', 'PRO'], + $contents + ); + + JFile::write($file, $contents); + } + + public function onBeforeInstall($route) + { + if ( ! $this->canInstall()) + { + return false; + } + + return true; + } + + public function onAfterInstall($route) + { + } + + public function delete($files = []) + { + foreach ($files as $file) + { + if (is_dir($file)) + { + JFolder::delete($file); + } + + if (is_file($file)) + { + JFile::delete($file); + } + } + } + + public function fixAssetsRules() + { + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('rules')) + ->from('#__assets') + ->where($this->db->quoteName('title') . ' = ' . $this->db->quote('com_' . $this->extname)); + $this->db->setQuery($query, 0, 1); + $rules = $this->db->loadResult(); + + $rules = json_decode($rules); + + if(empty($rules)) { + return; + } + + foreach($rules as $key => $value) { + if(!empty($value)) { + continue; + } + + unset($rules->$key); + } + + $rules = json_encode($rules); + + + $query = $this->db->getQuery(true) + ->update($this->db->quoteName('#__assets')) + ->set($this->db->quoteName('rules') . ' = ' . $this->db->quote($rules)) + ->where($this->db->quoteName('title') . ' = ' . $this->db->quote('com_' . $this->extname)); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function fixExtensionNames() + { + switch ($this->extension_type) + { + case 'module' : + $this->fixModuleNames(); + } + } + + private function fixModuleNames() + { + // Get module id + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('id')) + ->from('#__modules') + ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) + ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); + $this->db->setQuery($query, 0, 1); + $module_id = $this->db->loadResult(); + + if (empty($module_id)) + { + return; + } + + $title = 'Regular Labs - ' . JText::_($this->name); + + $query->clear() + ->update('#__modules') + ->set($this->db->quoteName('title') . ' = ' . $this->db->quote($title)) + ->where($this->db->quoteName('id') . ' = ' . (int) $module_id) + ->where($this->db->quoteName('title') . ' LIKE ' . $this->db->quote('NoNumber%')); + $this->db->setQuery($query); + $this->db->execute(); + + // Fix module assets + + // Get asset id + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('id')) + ->from('#__assets') + ->where($this->db->quoteName('name') . ' = ' . $this->db->quote('com_modules.module.' . (int) $module_id)) + ->where($this->db->quoteName('title') . ' LIKE ' . $this->db->quote('NoNumber%')); + $this->db->setQuery($query, 0, 1); + $asset_id = $this->db->loadResult(); + + if (empty($asset_id)) + { + return; + } + + $query->clear() + ->update('#__assets') + ->set($this->db->quoteName('title') . ' = ' . $this->db->quote($title)) + ->where($this->db->quoteName('id') . ' = ' . (int) $asset_id); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function updateUpdateSites() + { + $this->removeOldUpdateSites(); + $this->updateNamesInUpdateSites(); + $this->updateHttptoHttpsInUpdateSites(); + $this->removeDuplicateUpdateSite(); + $this->updateDownloadKey(); + } + + private function removeOldUpdateSites() + { + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('nonumber.nl%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + if ( ! $id) + { + return; + } + + $query->clear() + ->delete('#__update_sites') + ->where($this->db->quoteName('update_site_id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + + $query->clear() + ->delete('#__update_sites_extensions') + ->where($this->db->quoteName('update_site_id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function updateNamesInUpdateSites() + { + $name = JText::_($this->name); + if ($this->alias != 'extensionmanager') + { + $name = 'Regular Labs - ' . $name; + } + + $query = $this->db->getQuery(true) + ->update('#__update_sites') + ->set($this->db->quoteName('name') . ' = ' . $this->db->quote($name)) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function updateHttptoHttpsInUpdateSites() + { + $query = $this->db->getQuery(true) + ->update('#__update_sites') + ->set($this->db->quoteName('location') . ' = REPLACE(' + . $this->db->quoteName('location') . ', ' + . $this->db->quote('http://') . ', ' + . $this->db->quote('https://') + . ')') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('http://download.regularlabs.com%')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function removeDuplicateUpdateSite() + { + // First check to see if there is a pro entry + + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')) + ->where($this->db->quoteName('location') . ' NOT LIKE ' . $this->db->quote('%pro=1%')); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + // Otherwise just get the first match + if ( ! $id) + { + $query->clear() + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + // Remove pro=1 from the found update site + $query->clear() + ->update('#__update_sites') + ->set($this->db->quoteName('location') + . ' = replace(' . $this->db->quoteName('location') . ', ' . $this->db->quote('&pro=1') . ', ' . $this->db->quote('') . ')') + ->where($this->db->quoteName('update_site_id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + } + + if ( ! $id) + { + return; + } + + $query->clear() + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')) + ->where($this->db->quoteName('update_site_id') . ' != ' . $id); + $this->db->setQuery($query); + $ids = $this->db->loadColumn(); + + if (empty($ids)) + { + return; + } + + $query->clear() + ->delete('#__update_sites') + ->where($this->db->quoteName('update_site_id') . ' IN (' . implode(',', $ids) . ')'); + $this->db->setQuery($query); + $this->db->execute(); + + $query->clear() + ->delete('#__update_sites_extensions') + ->where($this->db->quoteName('update_site_id') . ' IN (' . implode(',', $ids) . ')'); + $this->db->setQuery($query); + $this->db->execute(); + } + + // Save the download key from the Regular Labs Extension Manager config to the update sites + private function updateDownloadKey() + { + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('params')) + ->from('#__extensions') + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote('com_regularlabsmanager')); + $this->db->setQuery($query); + $params = $this->db->loadResult(); + + if ( ! $params) + { + return; + } + + $params = json_decode($params); + + if ( ! isset($params->key)) + { + return; + } + + // Add the key on all regularlabs.com urls + $query->clear() + ->update('#__update_sites') + ->set($this->db->quoteName('extra_query') . ' = ' . $this->db->quote('k=' . $params->key)) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function removeAdminCache() + { + $this->delete([JPATH_ADMINISTRATOR . '/cache/regularlabs']); + $this->delete([JPATH_ADMINISTRATOR . '/cache/nonumber']); + } + + private function removeGlobalLanguageFiles() + { + if ($this->extension_type == 'library') + { + return; + } + + $language_files = JFolder::files(JPATH_ADMINISTRATOR . '/language', '\.' . $this->getPrefix() . '_' . $this->extname . '\.', true, true); + + // Remove override files + foreach ($language_files as $i => $language_file) + { + if (strpos($language_file, '/overrides/') === false) + { + continue; + } + + unset($language_files[$i]); + } + + if (empty($language_files)) + { + return; + } + + JFile::delete($language_files); + } + + private function removeUnusedLanguageFiles() + { + if ($this->extension_type == 'library') + { + return; + } + + $installed_languages = array_merge( + JFolder::folders(JPATH_SITE . '/language'), + JFolder::folders(JPATH_ADMINISTRATOR . '/language') + ); + + $languages = array_diff( + JFolder::folders(__DIR__ . '/language'), + $installed_languages + ); + + $delete_languages = []; + + foreach ($languages as $language) + { + $delete_languages[] = $this->getMainFolder() . '/language/' . $language; + } + + if (empty($delete_languages)) + { + return; + } + + // Remove folders + $this->delete($delete_languages); + } +} diff --git a/deployed/regularlabs/plugins/editors-xtd/sourcerer/script.install.php b/deployed/regularlabs/plugins/editors-xtd/sourcerer/script.install.php new file mode 100644 index 00000000..a774858c --- /dev/null +++ b/deployed/regularlabs/plugins/editors-xtd/sourcerer/script.install.php @@ -0,0 +1,27 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +require_once __DIR__ . '/script.install.helper.php'; + +class PlgEditorsXtdSourcererInstallerScript extends PlgEditorsXtdSourcererInstallerScriptHelper +{ + public $name = 'SOURCERER'; + public $alias = 'sourcerer'; + public $extension_type = 'plugin'; + public $plugin_folder = 'editors-xtd'; + + public function uninstall($adapter) + { + $this->uninstallPlugin($this->extname, 'system'); + } +} diff --git a/deployed/regularlabs/plugins/editors-xtd/sourcerer/sourcerer.php b/deployed/regularlabs/plugins/editors-xtd/sourcerer/sourcerer.php new file mode 100644 index 00000000..1e892dd5 --- /dev/null +++ b/deployed/regularlabs/plugins/editors-xtd/sourcerer/sourcerer.php @@ -0,0 +1,27 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + return; +} + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +/** + * Button Plugin that places a Sourcerer code block into the text + */ +class PlgButtonSourcerer + extends \RegularLabs\Library\EditorButtonPlugin +{ +} diff --git a/deployed/regularlabs/plugins/editors-xtd/sourcerer/sourcerer.xml b/deployed/regularlabs/plugins/editors-xtd/sourcerer/sourcerer.xml new file mode 100644 index 00000000..91ccaa81 --- /dev/null +++ b/deployed/regularlabs/plugins/editors-xtd/sourcerer/sourcerer.xml @@ -0,0 +1,41 @@ + + + plg_editors-xtd_sourcerer + PLG_EDITORS-XTD_SOURCERER_DESC + 7.4.0 + December 2018 + Regular Labs (Peter van Westen) + info@regularlabs.com + https://www.regularlabs.com + Copyright © 2018 Regular Labs - All Rights Reserved + http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + + script.install.php + + + sourcerer.php + popup.php + helper.php + script.install.helper.php + language + + + + +
+ + + + + + +
+
+
+
diff --git a/deployed/regularlabs/plugins/system/advancedmodules/advancedmodules.php b/deployed/regularlabs/plugins/system/advancedmodules/advancedmodules.php new file mode 100644 index 00000000..1d0ff1b0 --- /dev/null +++ b/deployed/regularlabs/plugins/system/advancedmodules/advancedmodules.php @@ -0,0 +1,72 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +// Do not instantiate plugin on install pages +// to prevent installation/update breaking because of potential breaking changes +if ( + in_array(JFactory::getApplication()->input->get('option'), ['com_installer', 'com_regularlabsmanager']) + && JFactory::getApplication()->input->get('action') != '' +) +{ + return; +} + +if ( ! is_file(__DIR__ . '/vendor/autoload.php')) +{ + return; +} + +require_once __DIR__ . '/vendor/autoload.php'; + +use RegularLabs\Library\Protect as RL_Protect; +use RegularLabs\Plugin\System\AdvancedModules\Plugin; + +class PlgSystemAdvancedModules extends Plugin +{ + public $_alias = 'advancedmodules'; + public $_title = 'ADVANCED_MODULE_MANAGER'; + public $_lang_prefix = 'AMM'; + + public $_page_types = ['html']; + public $_enable_in_admin = true; + + public function extraChecks() + { + if ( ! RL_Protect::isComponentInstalled('advancedmodules')) + { + return false; + } + + return true; + } + + /* + * Below are the events that this plugin uses + * All handling is passed along to the parent run method + */ + public function onAfterInitialise() + { + $this->run(); + } + + public function onAfterRoute() + { + $this->run(); + } + + public function onAfterRender() + { + $this->run(); + } +} + diff --git a/deployed/regularlabs/plugins/system/advancedmodules/advancedmodules.xml b/deployed/regularlabs/plugins/system/advancedmodules/advancedmodules.xml new file mode 100644 index 00000000..3b241599 --- /dev/null +++ b/deployed/regularlabs/plugins/system/advancedmodules/advancedmodules.xml @@ -0,0 +1,49 @@ + + + plg_system_advancedmodules + PLG_SYSTEM_ADVANCEDMODULES_DESC + 7.7.1 + July 2018 + Regular Labs (Peter van Westen) + info@regularlabs.com + https://www.regularlabs.com + Copyright © 2018 Regular Labs - All Rights Reserved + http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + + script.install.php + + + + https://download.regularlabs.com/updates.xml?e=advancedmodulemanager&type=.xml + + + + + advancedmodules.php + script.install.helper.php + language + src + vendor + + + + +
+ + + + + + + + +
+
+
+
diff --git a/deployed/regularlabs/plugins/system/advancedmodules/language/en-GB/en-GB.plg_system_advancedmodules.ini b/deployed/regularlabs/plugins/system/advancedmodules/language/en-GB/en-GB.plg_system_advancedmodules.ini new file mode 100644 index 00000000..e8b5c6a8 --- /dev/null +++ b/deployed/regularlabs/plugins/system/advancedmodules/language/en-GB/en-GB.plg_system_advancedmodules.ini @@ -0,0 +1,23 @@ +;; @package Advanced Module Manager +;; @version 7.7.1 +;; +;; @author Peter van Westen +;; @link http://www.regularlabs.com +;; @copyright Copyright © 2018 Regular Labs All Rights Reserved +;; @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL +;; +;; @translate Want to help with translations? See: https://www.regularlabs.com/translate + +PLG_SYSTEM_ADVANCEDMODULES="System - Regular Labs - Advanced Module Manager" +PLG_SYSTEM_ADVANCEDMODULES_DESC="Advanced Module Manager - take control over modules in Joomla!" +ADVANCED_MODULE_MANAGER="Advanced Module Manager" + +ADVANCED_MODULE_MANAGER_DESC="With Advanced Module Manager you have extra options and functionality to control your modules." + +AMM_EXTENSION_CAN_NOT_FUNCTION="[[%1:extension name%]] cannot function." +AMM_REGULAR_LABS_LIBRARY_NOT_ENABLED="Regular Labs Library plugin is not enabled." +AMM_REGULAR_LABS_LIBRARY_NOT_INSTALLED="Regular Labs Library plugin is not installed." +AMM_REGULAR_LABS_LIBRARY_OUTDATED="Regular Labs Library plugin is outdated. Try to re-install [[%1:extension name%]]." + +AMM_SETTINGS="Please see the [[%1:start link%]]Module Manager[[%2:end link%]] for settings." +AMM_THE_COMPONENT="the Advanced Module Manager component" diff --git a/deployed/regularlabs/plugins/system/advancedmodules/language/en-GB/en-GB.plg_system_advancedmodules.sys.ini b/deployed/regularlabs/plugins/system/advancedmodules/language/en-GB/en-GB.plg_system_advancedmodules.sys.ini new file mode 100644 index 00000000..cc6f87c8 --- /dev/null +++ b/deployed/regularlabs/plugins/system/advancedmodules/language/en-GB/en-GB.plg_system_advancedmodules.sys.ini @@ -0,0 +1,13 @@ +;; @package Advanced Module Manager +;; @version 7.7.1 +;; +;; @author Peter van Westen +;; @link http://www.regularlabs.com +;; @copyright Copyright © 2018 Regular Labs All Rights Reserved +;; @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL +;; +;; @translate Want to help with translations? See: https://www.regularlabs.com/translate + +PLG_SYSTEM_ADVANCEDMODULES="System - Regular Labs - Advanced Module Manager" +PLG_SYSTEM_ADVANCEDMODULES_DESC="Advanced Module Manager - take control over modules in Joomla!" +ADVANCED_MODULE_MANAGER="Advanced Module Manager" diff --git a/deployed/regularlabs/plugins/system/advancedmodules/language/hu-HU/hu-HU.plg_system_advancedmodules.ini b/deployed/regularlabs/plugins/system/advancedmodules/language/hu-HU/hu-HU.plg_system_advancedmodules.ini new file mode 100644 index 00000000..9ad54b41 --- /dev/null +++ b/deployed/regularlabs/plugins/system/advancedmodules/language/hu-HU/hu-HU.plg_system_advancedmodules.ini @@ -0,0 +1,25 @@ +;; @package Advanced Module Manager +;; @version 7.7.1 +;; +;; @author Peter van Westen +;; @link http://www.regularlabs.com +;; @copyright Copyright © 2018 Regular Labs All Rights Reserved +;; @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL +;; +;; @translate Want to help with translations? See: https://www.regularlabs.com/translate +;; +;; @translation Fordította: Csontos Balázs Joomla! Magyarország (joomlacms.hu) + +PLG_SYSTEM_ADVANCEDMODULES="Rendszer - Regular Labs - Advanced Module Manager" +PLG_SYSTEM_ADVANCEDMODULES_DESC="Advanced Module Manager - kibővített beállítások Joomla! modulok számára" +ADVANCED_MODULE_MANAGER="Advanced Module Manager" + +ADVANCED_MODULE_MANAGER_DESC="Az Advanced Module Manager használatával extra beállítások és további funkcionalitás érhető el a Joomla! modulok beállításai között." + +AMM_EXTENSION_CAN_NOT_FUNCTION="[[%1:extension name%]] nem működik." +AMM_REGULAR_LABS_LIBRARY_NOT_ENABLED="A Regular Labs keretrendszer beépülő-modul nincs engedélyezve." +AMM_REGULAR_LABS_LIBRARY_NOT_INSTALLED="A Regular Labs Library bővítmény nincs telepítve." +; AMM_REGULAR_LABS_LIBRARY_OUTDATED="Regular Labs Library plugin is outdated. Try to re-install [[%1:extension name%]]." + +AMM_SETTINGS="Kérlek tekintsd meg a [[%1:start link%]]Modulkezelő[[%2:end link%]] beállításait." +AMM_THE_COMPONENT="Az Advanced Module Manager komponens" diff --git a/deployed/regularlabs/plugins/system/advancedmodules/language/hu-HU/hu-HU.plg_system_advancedmodules.sys.ini b/deployed/regularlabs/plugins/system/advancedmodules/language/hu-HU/hu-HU.plg_system_advancedmodules.sys.ini new file mode 100644 index 00000000..6c6288dc --- /dev/null +++ b/deployed/regularlabs/plugins/system/advancedmodules/language/hu-HU/hu-HU.plg_system_advancedmodules.sys.ini @@ -0,0 +1,15 @@ +;; @package Advanced Module Manager +;; @version 7.7.1 +;; +;; @author Peter van Westen +;; @link http://www.regularlabs.com +;; @copyright Copyright © 2018 Regular Labs All Rights Reserved +;; @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL +;; +;; @translate Want to help with translations? See: https://www.regularlabs.com/translate +;; +;; @translation Fordította: Csontos Balázs Joomla! Magyarország (joomlacms.hu) + +PLG_SYSTEM_ADVANCEDMODULES="Rendszer - Regular Labs - Advanced Module Manager" +PLG_SYSTEM_ADVANCEDMODULES_DESC="Advanced Module Manager - kibővített beállítások Joomla! modulok számára" +ADVANCED_MODULE_MANAGER="Advanced Module Manager" diff --git a/deployed/regularlabs/plugins/system/advancedmodules/script.install.helper.php b/deployed/regularlabs/plugins/system/advancedmodules/script.install.helper.php new file mode 100644 index 00000000..a113b19e --- /dev/null +++ b/deployed/regularlabs/plugins/system/advancedmodules/script.install.helper.php @@ -0,0 +1,852 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +class PlgSystemAdvancedModulesInstallerScriptHelper +{ + public $name = ''; + public $alias = ''; + public $extname = ''; + public $extension_type = ''; + public $plugin_folder = 'system'; + public $module_position = 'status'; + public $client_id = 1; + public $install_type = 'install'; + public $show_message = true; + public $db = null; + public $softbreak = null; + + public function __construct(&$params) + { + $this->extname = $this->extname ?: $this->alias; + $this->db = JFactory::getDbo(); + } + + public function preflight($route, JAdapterInstance $adapter) + { + if ( ! in_array($route, ['install', 'update'])) + { + return true; + } + + JFactory::getLanguage()->load('plg_system_regularlabsinstaller', JPATH_PLUGINS . '/system/regularlabsinstaller'); + + if ($this->show_message && $this->isInstalled()) + { + $this->install_type = 'update'; + } + + if ($this->onBeforeInstall($route) === false) + { + return false; + } + + return true; + } + + public function postflight($route, JAdapterInstance $adapter) + { + $this->removeGlobalLanguageFiles(); + $this->removeUnusedLanguageFiles(); + + JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); + + if ( ! in_array($route, ['install', 'update'])) + { + return true; + } + + $this->fixExtensionNames(); + $this->updateUpdateSites(); + $this->removeAdminCache(); + + if ($this->onAfterInstall($route) === false) + { + return false; + } + + if ($route == 'install') + { + $this->publishExtension(); + } + + if ($this->show_message) + { + $this->addInstalledMessage(); + } + + JFactory::getCache()->clean('com_plugins'); + JFactory::getCache()->clean('_system'); + + return true; + } + + public function isInstalled() + { + if ( ! is_file($this->getInstalledXMLFile())) + { + return false; + } + + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('extension_id')) + ->from('#__extensions') + ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); + $this->db->setQuery($query, 0, 1); + $result = $this->db->loadResult(); + + return empty($result) ? false : true; + } + + public function getMainFolder() + { + switch ($this->extension_type) + { + case 'plugin' : + return JPATH_PLUGINS . '/' . $this->plugin_folder . '/' . $this->extname; + + case 'component' : + return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; + + case 'module' : + return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; + + case 'library' : + return JPATH_SITE . '/libraries/' . $this->extname; + } + } + + public function getInstalledXMLFile() + { + return $this->getXMLFile($this->getMainFolder()); + } + + public function getCurrentXMLFile() + { + return $this->getXMLFile(__DIR__); + } + + public function getXMLFile($folder) + { + switch ($this->extension_type) + { + case 'module' : + return $folder . '/mod_' . $this->extname . '.xml'; + + default : + return $folder . '/' . $this->extname . '.xml'; + } + } + + public function uninstallExtension($extname, $type = 'plugin', $folder = 'system', $show_message = true) + { + if (empty($extname)) + { + return; + } + + $folders = []; + + switch ($type) + { + case 'plugin'; + $folders[] = JPATH_PLUGINS . '/' . $folder . '/' . $extname; + break; + + case 'component': + $folders[] = JPATH_ADMINISTRATOR . '/components/com_' . $extname; + $folders[] = JPATH_SITE . '/components/com_' . $extname; + break; + + case 'module': + $folders[] = JPATH_ADMINISTRATOR . '/modules/mod_' . $extname; + $folders[] = JPATH_SITE . '/modules/mod_' . $extname; + break; + } + + if ( ! $this->foldersExist($folders)) + { + return; + } + + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('extension_id')) + ->from('#__extensions') + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName($type, $extname))) + ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($type)); + + if ($type == 'plugin') + { + $query->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($folder)); + } + + $this->db->setQuery($query); + $ids = $this->db->loadColumn(); + + if (empty($ids)) + { + foreach ($folders as $folder) + { + JFolder::delete($folder); + } + + return; + } + + $ignore_ids = JFactory::getApplication()->getUserState('rl_ignore_uninstall_ids', []); + + if (JFactory::getApplication()->input->get('option') == 'com_installer' && JFactory::getApplication()->input->get('task') == 'remove') + { + // Don't attempt to uninstall extensions that are already selected to get uninstalled by them selves + $ignore_ids = array_merge($ignore_ids, JFactory::getApplication()->input->get('cid', [], 'array')); + JFactory::getApplication()->input->set('cid', array_merge($ignore_ids, $ids)); + } + + $ids = array_diff($ids, $ignore_ids); + + if (empty($ids)) + { + return; + } + + $ignore_ids = array_merge($ignore_ids, $ids); + JFactory::getApplication()->setUserState('rl_ignore_uninstall_ids', $ignore_ids); + + foreach ($ids as $id) + { + $tmpInstaller = new JInstaller; + $tmpInstaller->uninstall($type, $id); + } + + if ($show_message) + { + JFactory::getApplication()->enqueueMessage( + JText::sprintf( + 'COM_INSTALLER_UNINSTALL_SUCCESS', + JText::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($type)) + ) + ); + } + } + + public function foldersExist($folders = []) + { + foreach ($folders as $folder) + { + if (is_dir($folder)) + { + return true; + } + } + + return false; + } + + public function uninstallPlugin($extname, $folder = 'system', $show_message = true) + { + $this->uninstallExtension($extname, 'plugin', $folder, $show_message); + } + + public function uninstallComponent($extname, $show_message = true) + { + $this->uninstallExtension($extname, 'component', null, $show_message); + } + + public function uninstallModule($extname, $show_message = true) + { + $this->uninstallExtension($extname, 'module', null, $show_message); + } + + public function publishExtension() + { + switch ($this->extension_type) + { + case 'plugin' : + $this->publishPlugin(); + + case 'module' : + $this->publishModule(); + } + } + + public function publishPlugin() + { + $query = $this->db->getQuery(true) + ->update('#__extensions') + ->set($this->db->quoteName('enabled') . ' = 1') + ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) + ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); + $this->db->setQuery($query); + $this->db->execute(); + } + + public function publishModule() + { + // Get module id + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('id')) + ->from('#__modules') + ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) + ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + if ( ! $id) + { + return; + } + + // check if module is already in the modules_menu table (meaning is is already saved) + $query->clear() + ->select($this->db->quoteName('moduleid')) + ->from('#__modules_menu') + ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); + $this->db->setQuery($query, 0, 1); + $exists = $this->db->loadResult(); + + if ($exists) + { + return; + } + + // Get highest ordering number in position + $query->clear() + ->select($this->db->quoteName('ordering')) + ->from('#__modules') + ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) + ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) + ->order('ordering DESC'); + $this->db->setQuery($query, 0, 1); + $ordering = $this->db->loadResult(); + $ordering++; + + // publish module and set ordering number + $query->clear() + ->update('#__modules') + ->set($this->db->quoteName('published') . ' = 1') + ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) + ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) + ->where($this->db->quoteName('id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + + // add module to the modules_menu table + $query->clear() + ->insert('#__modules_menu') + ->columns([$this->db->quoteName('moduleid'), $this->db->quoteName('menuid')]) + ->values((int) $id . ', 0'); + $this->db->setQuery($query); + $this->db->execute(); + } + + public function addInstalledMessage() + { + JFactory::getApplication()->enqueueMessage( + JText::sprintf( + JText::_($this->install_type == 'update' ? 'RLI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'RLI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), + '' . JText::_($this->name) . '', + '' . $this->getVersion() . '', + $this->getFullType() + ) + ); + } + + public function getPrefix() + { + switch ($this->extension_type) + { + case 'plugin'; + return JText::_('plg_' . strtolower($this->plugin_folder)); + + case 'component': + return JText::_('com'); + + case 'module': + return JText::_('mod'); + + case 'library': + return JText::_('lib'); + + default: + return $this->extension_type; + } + } + + public function getElementName($type = null, $extname = null) + { + $type = is_null($type) ? $this->extension_type : $type; + $extname = is_null($extname) ? $this->extname : $extname; + + switch ($type) + { + case 'component' : + return 'com_' . $extname; + + case 'module' : + return 'mod_' . $extname; + + case 'plugin' : + default: + return $extname; + } + } + + public function getFullType() + { + return JText::_('RLI_' . strtoupper($this->getPrefix())); + } + + public function getVersion($file = '') + { + $file = $file ?: $this->getCurrentXMLFile(); + + if ( ! is_file($file)) + { + return ''; + } + + $xml = JApplicationHelper::parseXMLInstallFile($file); + + if ( ! $xml || ! isset($xml['version'])) + { + return ''; + } + + return $xml['version']; + } + + public function isNewer() + { + if ( ! $installed_version = $this->getVersion($this->getInstalledXMLFile())) + { + return true; + } + + $package_version = $this->getVersion(); + + return version_compare($installed_version, $package_version, '<='); + } + + public function canInstall() + { + // The extension is not installed yet + if ( ! $installed_version = $this->getVersion($this->getInstalledXMLFile())) + { + return true; + } + + // The free version is installed. So any version is ok to install + if (strpos($installed_version, 'PRO') === false) + { + return true; + } + + // Current package is a pro version, so all good + if (strpos($this->getVersion(), 'PRO') !== false) + { + return true; + } + + JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); + + JFactory::getApplication()->enqueueMessage(JText::_('RLI_ERROR_PRO_TO_FREE'), 'error'); + + JFactory::getApplication()->enqueueMessage( + html_entity_decode( + JText::sprintf( + 'RLI_ERROR_UNINSTALL_FIRST', + '', + '', + JText::_($this->name) + ) + ), 'error' + ); + + return false; + } + + /* + * Fixes incorrectly formed versions because of issues in old packager + */ + public function fixFileVersions($file) + { + if (is_array($file)) + { + foreach ($file as $f) + { + self::fixFileVersions($f); + } + + return; + } + + if ( ! is_string($file) || ! is_file($file)) + { + return; + } + + $contents = file_get_contents($file); + + if ( + strpos($contents, 'FREEFREE') === false + && strpos($contents, 'FREEPRO') === false + && strpos($contents, 'PROFREE') === false + && strpos($contents, 'PROPRO') === false + ) + { + return; + } + + $contents = str_replace( + ['FREEFREE', 'FREEPRO', 'PROFREE', 'PROPRO'], + ['FREE', 'PRO', 'FREE', 'PRO'], + $contents + ); + + JFile::write($file, $contents); + } + + public function onBeforeInstall($route) + { + if ( ! $this->canInstall()) + { + return false; + } + + return true; + } + + public function onAfterInstall($route) + { + } + + public function delete($files = []) + { + foreach ($files as $file) + { + if (is_dir($file)) + { + JFolder::delete($file); + } + + if (is_file($file)) + { + JFile::delete($file); + } + } + } + + public function fixAssetsRules($rules = '{"core.admin":[],"core.manage":[]}') + { + // replace default rules value {} with the correct initial value + $query = $this->db->getQuery(true) + ->update($this->db->quoteName('#__assets')) + ->set($this->db->quoteName('rules') . ' = ' . $this->db->quote($rules)) + ->where($this->db->quoteName('title') . ' = ' . $this->db->quote('com_' . $this->extname)) + ->where($this->db->quoteName('rules') . ' = ' . $this->db->quote('{}')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function fixExtensionNames() + { + switch ($this->extension_type) + { + case 'module' : + $this->fixModuleNames(); + } + } + + private function fixModuleNames() + { + // Get module id + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('id')) + ->from('#__modules') + ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) + ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); + $this->db->setQuery($query, 0, 1); + $module_id = $this->db->loadResult(); + + if (empty($module_id)) + { + return; + } + + $title = 'Regular Labs - ' . JText::_($this->name); + + $query->clear() + ->update('#__modules') + ->set($this->db->quoteName('title') . ' = ' . $this->db->quote($title)) + ->where($this->db->quoteName('id') . ' = ' . (int) $module_id) + ->where($this->db->quoteName('title') . ' LIKE ' . $this->db->quote('NoNumber%')); + $this->db->setQuery($query); + $this->db->execute(); + + // Fix module assets + + // Get asset id + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('id')) + ->from('#__assets') + ->where($this->db->quoteName('name') . ' = ' . $this->db->quote('com_modules.module.' . (int) $module_id)) + ->where($this->db->quoteName('title') . ' LIKE ' . $this->db->quote('NoNumber%')); + $this->db->setQuery($query, 0, 1); + $asset_id = $this->db->loadResult(); + + if (empty($asset_id)) + { + return; + } + + $query->clear() + ->update('#__assets') + ->set($this->db->quoteName('title') . ' = ' . $this->db->quote($title)) + ->where($this->db->quoteName('id') . ' = ' . (int) $asset_id); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function updateUpdateSites() + { + $this->removeOldUpdateSites(); + $this->updateNamesInUpdateSites(); + $this->updateHttptoHttpsInUpdateSites(); + $this->removeDuplicateUpdateSite(); + $this->updateDownloadKey(); + } + + private function removeOldUpdateSites() + { + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('nonumber.nl%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + if ( ! $id) + { + return; + } + + $query->clear() + ->delete('#__update_sites') + ->where($this->db->quoteName('update_site_id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + + $query->clear() + ->delete('#__update_sites_extensions') + ->where($this->db->quoteName('update_site_id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function updateNamesInUpdateSites() + { + $name = JText::_($this->name); + if ($this->alias != 'extensionmanager') + { + $name = 'Regular Labs - ' . $name; + } + + $query = $this->db->getQuery(true) + ->update('#__update_sites') + ->set($this->db->quoteName('name') . ' = ' . $this->db->quote($name)) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function updateHttptoHttpsInUpdateSites() + { + $query = $this->db->getQuery(true) + ->update('#__update_sites') + ->set($this->db->quoteName('location') . ' = REPLACE(' + . $this->db->quoteName('location') . ', ' + . $this->db->quote('http://') . ', ' + . $this->db->quote('https://') + . ')') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('http://download.regularlabs.com%')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function removeDuplicateUpdateSite() + { + // First check to see if there is a pro entry + + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')) + ->where($this->db->quoteName('location') . ' NOT LIKE ' . $this->db->quote('%pro=1%')); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + // Otherwise just get the first match + if ( ! $id) + { + $query->clear() + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + // Remove pro=1 from the found update site + $query->clear() + ->update('#__update_sites') + ->set($this->db->quoteName('location') + . ' = replace(' . $this->db->quoteName('location') . ', ' . $this->db->quote('&pro=1') . ', ' . $this->db->quote('') . ')') + ->where($this->db->quoteName('update_site_id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + } + + if ( ! $id) + { + return; + } + + $query->clear() + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')) + ->where($this->db->quoteName('update_site_id') . ' != ' . $id); + $this->db->setQuery($query); + $ids = $this->db->loadColumn(); + + if (empty($ids)) + { + return; + } + + $query->clear() + ->delete('#__update_sites') + ->where($this->db->quoteName('update_site_id') . ' IN (' . implode(',', $ids) . ')'); + $this->db->setQuery($query); + $this->db->execute(); + + $query->clear() + ->delete('#__update_sites_extensions') + ->where($this->db->quoteName('update_site_id') . ' IN (' . implode(',', $ids) . ')'); + $this->db->setQuery($query); + $this->db->execute(); + } + + // Save the download key from the Regular Labs Extension Manager config to the update sites + private function updateDownloadKey() + { + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('params')) + ->from('#__extensions') + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote('com_regularlabsmanager')); + $this->db->setQuery($query); + $params = $this->db->loadResult(); + + if ( ! $params) + { + return; + } + + $params = json_decode($params); + + if ( ! isset($params->key)) + { + return; + } + + // Add the key on all regularlabs.com urls + $query->clear() + ->update('#__update_sites') + ->set($this->db->quoteName('extra_query') . ' = ' . $this->db->quote('k=' . $params->key)) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function removeAdminCache() + { + $this->delete([JPATH_ADMINISTRATOR . '/cache/regularlabs']); + $this->delete([JPATH_ADMINISTRATOR . '/cache/nonumber']); + } + + private function removeGlobalLanguageFiles() + { + if ($this->extension_type == 'library') + { + return; + } + + $language_files = JFolder::files(JPATH_ADMINISTRATOR . '/language', '\.' . $this->getPrefix() . '_' . $this->extname . '\.', true, true); + + // Remove override files + foreach ($language_files as $i => $language_file) + { + if (strpos($language_file, '/overrides/') === false) + { + continue; + } + + unset($language_files[$i]); + } + + if (empty($language_files)) + { + return; + } + + JFile::delete($language_files); + } + + private function removeUnusedLanguageFiles() + { + if ($this->extension_type == 'library') + { + return; + } + + $installed_languages = array_merge( + JFolder::folders(JPATH_SITE . '/language'), + JFolder::folders(JPATH_ADMINISTRATOR . '/language') + ); + + $languages = array_diff( + JFolder::folders(__DIR__ . '/language'), + $installed_languages + ); + + $delete_languages = []; + + foreach ($languages as $language) + { + $delete_languages[] = $this->getMainFolder() . '/language/' . $language; + } + + if (empty($delete_languages)) + { + return; + } + + // Remove folders + $this->delete($delete_languages); + } +} diff --git a/deployed/regularlabs/plugins/system/advancedmodules/script.install.php b/deployed/regularlabs/plugins/system/advancedmodules/script.install.php new file mode 100644 index 00000000..c22f5d21 --- /dev/null +++ b/deployed/regularlabs/plugins/system/advancedmodules/script.install.php @@ -0,0 +1,46 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +require_once __DIR__ . '/script.install.helper.php'; + +class PlgSystemAdvancedModulesInstallerScript extends PlgSystemAdvancedModulesInstallerScriptHelper +{ + public $name = 'ADVANCED_MODULE_MANAGER'; + public $alias = 'advancedmodulemanager'; + public $extname = 'advancedmodules'; + public $extension_type = 'plugin'; + + public function uninstall($adapter) + { + $this->uninstallComponent($this->extname); + } + + public function onAfterInstall($route) + { + $this->setPluginOrdering(); + } + + private function setPluginOrdering() + { + $query = $this->db->getQuery(true) + ->update('#__extensions') + ->set($this->db->quoteName('ordering') . ' = -1') + ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote('advancedmodules')) + ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote('system')); + $this->db->setQuery($query); + $this->db->execute(); + + JFactory::getCache()->clean('_system'); + } +} diff --git a/deployed/regularlabs/plugins/system/advancedmodules/src/Document.php b/deployed/regularlabs/plugins/system/advancedmodules/src/Document.php new file mode 100644 index 00000000..041bda67 --- /dev/null +++ b/deployed/regularlabs/plugins/system/advancedmodules/src/Document.php @@ -0,0 +1,144 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Plugin\System\AdvancedModules; + +defined('_JEXEC') or die; + +use JFactory; +use JHtml; +use JRoute; +use JText; +use RegularLabs\Library\Document as RL_Document; +use RegularLabs\Library\Language as RL_Language; +use RegularLabs\Library\RegEx as RL_RegEx; + +class Document +{ + public static function loadFrontEditScript() + { + if ( ! JFactory::getUser()->authorise('core.edit', 'com_menus') + || ! JFactory::getApplication()->get('frontediting', 1) == 2 + ) + { + return; + } + + JHtml::_('jquery.framework'); + + RL_Document::script('advancedmodules/frontediting.min.js', '7.7.1'); + } + + /* + * Replace links to com_modules with com_advancedmodules + */ + public static function replaceLinks() + { + if (RL_Document::isClient('administrator') && JFactory::getApplication()->input->get('option') == 'com_modules') + { + self::replaceLinksInCoreModuleManager(); + + return; + } + + $params = Params::get(); + + $body = JFactory::getApplication()->getBody(); + + // Replace in link specifically in frontend + if (RL_Document::isClient('site') && $params->replace_urls_frontend) + { + self::replaceLinksInFrontend($body); + } + + // Replace remaining links in modules in admin and frontend + if ( ! RL_Document::isClient('site') || $params->replace_urls_frontend) + { + self::replaceLinksModules($body); + } + + JFactory::getApplication()->setBody($body); + } + + private static function replaceLinksModules(&$string) + { + if (strpos($string, 'com_modules') === false) + { + return; + } + + $string = RL_RegEx::replace( + '((["\'])[^\s"\'%]*\?option=com_)(modules[^a-z-_ "\']*?\2)', + '\1advanced\3', + $string + ); + + $string = str_replace( + [ + '?option=com_advancedmodules&force=1', + '?option=com_advancedmodules&force=1', + ], + '?option=com_modules', + $string + ); + } + + private static function replaceLinksInFrontend(&$string) + { + if (strpos($string, 'jmodediturl=') === false) + { + return; + } + + $params = Params::get(); + + $url = 'index.php?option=com_advancedmodules&view=edit&task=edit'; + + if (JFactory::getUser()->authorise('core.manage', 'com_modules') && $params->use_admin_from_frontend) + { + $url = 'administrator/index.php?option=com_advancedmodules&task=module.edit'; + } + + $frontend_urls = [ + 'index.php?option=com_config&controller=config.display.modules', + 'administrator/index.php?option=com_modules&view=module&layout=edit', + ]; + + array_walk($frontend_urls, function (&$value) { + $value = RL_RegEx::quote($value); + }); + + $string = RL_RegEx::replace( + '(jmodediturl="[^"]*)(' . implode('|', $frontend_urls) . ')', + '\1' . $url, + $string + ); + } + + private static function replaceLinksInCoreModuleManager() + { + RL_Language::load('com_advancedmodules'); + + $body = JFactory::getApplication()->getBody(); + + $url = 'index.php?option=com_advancedmodules'; + + if (JFactory::getApplication()->input->get('view') == 'module') + { + $url .= '&task=module.edit&id=' . (int) JFactory::getApplication()->input->get('id'); + } + + $link = '' . JText::_('AMM_SWITCH_TO_ADVANCED_MODULE_MANAGER') . '
'; + $body = RL_RegEx::replace('(
\s*\s*(<\!--.*?-->\s*)*
)', $link . '\1', $body); + + JFactory::getApplication()->setBody($body); + } +} diff --git a/deployed/regularlabs/plugins/system/advancedmodules/src/Helper.php b/deployed/regularlabs/plugins/system/advancedmodules/src/Helper.php new file mode 100644 index 00000000..7c0d356e --- /dev/null +++ b/deployed/regularlabs/plugins/system/advancedmodules/src/Helper.php @@ -0,0 +1,55 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Plugin\System\AdvancedModules; + +defined('_JEXEC') or die; + +use RegularLabs\Library\Document as RL_Document; + +class Helper +{ + public function onAfterInitialise() + { + if (Params::get()->initialise_event != 'onAfterRoute') + { + $this->initialise(); + } + } + + public function onAfterRoute() + { + if ( ! RL_Document::isAdmin()) + { + Document::loadFrontEditScript(); + } + + if (Params::get()->initialise_event == 'onAfterRoute') + { + $this->initialise(); + } + } + + public function initialise() + { + if (RL_Document::isAdmin()) + { + return; + } + + ModuleHelper::registerEvents(); + } + + public function onAfterRender() + { + Document::replaceLinks(); + } +} diff --git a/deployed/regularlabs/plugins/system/advancedmodules/src/Helpers/advancedmodulehelper.php b/deployed/regularlabs/plugins/system/advancedmodules/src/Helpers/advancedmodulehelper.php new file mode 100644 index 00000000..3171e462 --- /dev/null +++ b/deployed/regularlabs/plugins/system/advancedmodules/src/Helpers/advancedmodulehelper.php @@ -0,0 +1,514 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +jimport('joomla.filesystem.file'); + +use RegularLabs\Library\Conditions as RL_Conditions; +use RegularLabs\Library\Document as RL_Document; +use RegularLabs\Library\Parameters as RL_Parameters; +use RegularLabs\Library\RegEx as RL_RegEx; + +/* + * ModuleHelper methods + */ + +class PlgSystemAdvancedModuleHelper +{ + var $mirror_ids = []; + + public function onRenderModule(&$module) + { + // Module already nulled + if (is_null($module)) + { + return; + } + + // Do nothing if is not frontend + if ( ! RL_Document::isClient('site')) + { + return; + } + + // return true if module is empty (this will empty the content) + if ($this->isEmpty($module)) + { + $module = null; + + return; + } + + } + + public function isEmpty(&$module) + { + if ( ! isset($module->content)) + { + return true; + } + + $this->setAdvancedParams($module); + + // return false if module params are not found + if (empty($module->advancedparams)) + { + return false; + } + + $params = $module->advancedparams; + + // return false if hideempty is off in module params + if (empty($params) || ! isset($params->hideempty) || ! $params->hideempty) + { + return false; + } + + $config = $this->getConfig(); + + // return false if show_hideempty is off in main config + if ( ! $config->show_hideempty) + { + return false; + } + + $content = trim($module->content); + + // return true if module is empty + if ($content == '') + { + return true; + } + + // remove html and hidden whitespace + $content = str_replace(chr(194) . chr(160), ' ', $content); + $content = str_replace([' ', ' '], ' ', $content); + // remove comment tags + $content = RL_RegEx::replace('<\!--.*?-->', '', $content); + // remove all closing tags + $content = RL_RegEx::replace(']+>', '', $content); + // remove tags to be ignored + $tags = 'p|div|span|strong|b|em|i|ul|font|br|h[0-9]|fieldset|label|ul|ol|li|table|thead|tbody|tfoot|tr|th|td|form'; + $search = '<(?:' . $tags . ')(?:\s[^>]*)?>'; + + if (RL_RegEx::match($search, $content)) + { + $content = RL_RegEx::replace($search, '', $content); + } + + // return whether content is empty + return (trim($content) == ''); + } + + + public function onPrepareModuleList(&$modules) + { + // return if is not frontend + if ( ! RL_Document::isClient('site')) + { + return; + } + + jimport('joomla.filesystem.file'); + + $modules = is_null($modules) ? $this->getModuleList() : $modules; + + if (is_array($modules) && empty($modules)) + { + return; + } + + $filtered_modules = []; + + foreach ($modules as $module) + { + if (empty($module->id)) + { + continue; + } + + $module->name = substr($module->module, 4); + + if (JFactory::getApplication()->input->get('option') == 'com_ajax') + { + $filtered_modules[] = $module; + continue; + } + + $this->setAdvancedParams($module); + + if ($module->advancedparams === 0) + { + if (isset($module->published) && ! $module->published) + { + continue; + } + + $filtered_modules[] = $module; + + continue; + } + + + $module->reverse = 0; + + $this->setMirrorParams($module); + + $this->removeDisabledAssignments($module->advancedparams); + + AdvancedModules::setCurrentModule($module); + + $assignments = RL_Conditions::getConditionsFromParams($module->advancedparams); + $module->published = RL_Conditions::pass( + $assignments, + $module->advancedparams->match_method, + null, + $module + ); + + if ($module->reverse) + { + $module->published = ! $module->published; + } + + if (isset($module->published) && ! $module->published) + { + continue; + } + + $filtered_modules[] = $module; + } + + $modules = array_values($filtered_modules); + unset($filtered_modules); + } + + private function setAdvancedParams(&$module) + { + if (empty($module->id)) + { + return; + } + + if (isset($module->advancedparams) && is_object($module->advancedparams)) + { + return; + } + + if ( ! isset($module->advancedparams)) + { + $module->advancedparams = $this->getAdvancedParams($module); + } + + $module->advancedparams = json_decode($module->advancedparams); + + if (is_null($module->advancedparams)) + { + $module->advancedparams = (object) []; + } + + if ( + ! isset($module->advancedparams->assignto_menuitems) + || isset($module->advancedparams->assignto_urls_selection_sef) + || ( + ! is_array($module->advancedparams->assignto_menuitems) + && strpos($module->advancedparams->assignto_menuitems, '|') !== false + ) + ) + { + require_once JPATH_ADMINISTRATOR . '/components/com_advancedmodules/models/module.php'; + $model = new AdvancedModulesModelModule; + + $module->advancedparams = (object) $model->initAssignments($module->id, $module); + } + + $xmlfile_assignments = JPATH_ADMINISTRATOR . '/components/com_advancedmodules/assignments.xml'; + + $use_cache = isset($module->use_amm_cache) ? $module->use_amm_cache : true; + + $module->advancedparams = RL_Parameters::getInstance()->getParams($module->advancedparams, $xmlfile_assignments, '', $use_cache); + } + + private function setMirrorParams(&$module) + { + $module->mirror_id = $this->getMirrorModuleId($module); + + if (empty($module->mirror_id)) + { + return; + } + + $parameters = RL_Parameters::getInstance(); + + $mirror_id = $module->mirror_id < 0 ? $module->mirror_id * -1 : $module->mirror_id; + + $count = 0; + while ($count++ < 10) + { + if ( ! $test_mirrorid = $this->getMirrorModuleIdById($mirror_id)) + { + break; + } + + $mirror_id = $test_mirrorid; + } + + if (empty($mirror_id)) + { + return; + } + + $xmlfile_assignments = JPATH_ADMINISTRATOR . '/components/com_advancedmodules/assignments.xml'; + + $module->reverse = $module->mirror_id < 0; + + if ($mirror_id == $module->id) + { + $empty = (object) []; + $mirror_params = $parameters->getParams($empty, $xmlfile_assignments); + } + else + { + if (isset($modules[$mirror_id])) + { + if ( ! isset($modules[$mirror_id]->advancedparams)) + { + $modules[$mirror_id]->advancedparams = $this->getAdvancedParamsById($mirror_id); + $modules[$mirror_id]->advancedparams = $parameters->getParams($modules[$mirror_id]->advancedparams, $xmlfile_assignments); + } + + $mirror_params = $modules[$mirror_id]->advancedparams; + } + else + { + $mirror_params = $this->getAdvancedParamsById($mirror_id); + $mirror_params = $parameters->getParams($mirror_params, $xmlfile_assignments); + } + } + + // Keep the advanced settings that shouldn't be mirrored + $settings_to_keep = [ + 'hideempty', 'color', + ]; + + foreach ($settings_to_keep as $key) + { + if ( ! isset($module->advancedparams->{$key})) + { + continue; + } + + $mirror_params->{$key} = $module->advancedparams->{$key}; + } + + $module->advancedparams = $mirror_params; + } + + private function removeDisabledAssignments(&$params) + { + $config = $this->getConfig(); + + if ( ! $config->show_assignto_homepage) + { + $params->assignto_homepage = 0; + } + if ( ! $config->show_assignto_usergrouplevels) + { + $params->assignto_usergrouplevels = 0; + } + if ( ! $config->show_assignto_date) + { + $params->assignto_date = 0; + } + if ( ! $config->show_assignto_languages) + { + $params->assignto_languages = 0; + } + if ( ! $config->show_assignto_templates) + { + $params->assignto_templates = 0; + } + if ( ! $config->show_assignto_urls) + { + $params->assignto_urls = 0; + } + if ( ! $config->show_assignto_devices) + { + $params->assignto_devices = 0; + } + if ( ! $config->show_assignto_os) + { + $params->assignto_os = 0; + } + if ( ! $config->show_assignto_browsers) + { + $params->assignto_browsers = 0; + } + if ( ! $config->show_assignto_components) + { + $params->assignto_components = 0; + } + if ( ! $config->show_assignto_tags) + { + $params->show_assignto_tags = 0; + } + if ( ! $config->show_assignto_content) + { + $params->assignto_contentpagetypes = 0; + $params->assignto_cats = 0; + $params->assignto_articles = 0; + } + } + + + private function getModuleList() + { + $app = JFactory::getApplication(); + $groups = implode(',', JFactory::getUser()->getAuthorisedViewLevels()); + $lang = JFactory::getLanguage()->getTag(); + $clientId = (int) $app->getClientId(); + + $db = JFactory::getDbo(); + + $query = $db->getQuery(true) + ->select('m.id, m.title, m.module, m.position, m.content, m.showtitle, m.params') + ->select('am.mirror_id, am.params AS advancedparams, 0 AS menuid, m.publish_up, m.publish_down') + ->from('#__modules AS m') + ->join('LEFT', '#__extensions AS e ON e.element = m.module AND e.client_id = m.client_id') + ->join('LEFT', '#__advancedmodules as am ON am.moduleid = m.id') + ->where('m.published = 1') + ->where('e.enabled = 1') + ->where('m.access IN (' . $groups . ')') + ->where('m.client_id = ' . $clientId); + + // Filter by language + if ($app->isClient('site') && $app->getLanguageFilter()) + { + $query->where('m.language IN (' . $db->quote($lang) . ',' . $db->quote('*') . ')'); + } + + $query->order('m.position, m.ordering'); + + // Set the query + $db->setQuery($query); + + try + { + $modules = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + JLog::add(JText::sprintf('JLIB_APPLICATION_ERROR_MODULE_LOAD', $e->getMessage()), JLog::WARNING, 'jerror'); + + return []; + } + + return array_values($modules); + } + + private function getConfig() + { + static $instance; + + if (is_object($instance)) + { + return $instance; + } + + $instance = RL_Parameters::getInstance()->getComponentParams('advancedmodules'); + + return $instance; + } + + private function getMirrorModuleId($module) + { + if (isset($module->mirror_id)) + { + return $module->mirror_id; + } + + return $this->getMirrorModuleIdById($module->id); + } + + private function getMirrorModuleIdById($id) + { + if (isset($this->mirror_ids[$id])) + { + return $this->mirror_ids[$id]; + } + + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('a.mirror_id') + ->from('#__advancedmodules AS a') + ->where('a.moduleid = ' . (int) $id); + $db->setQuery($query); + + $this->mirror_ids[$id] = $db->loadResult(); + + return $this->mirror_ids[$id]; + } + + private function getAdvancedParams($module) + { + if (empty($module->id)) + { + return '{}'; + } + + if (isset($module->adv_params)) + { + return $module->adv_params; + } + + return $this->getAdvancedParamsById($module->id); + } + + private function getAdvancedParamsById($id = 0) + { + if ( ! $id) + { + return '{}'; + } + + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('a.params') + ->from('#__advancedmodules AS a') + ->where('a.moduleid = ' . (int) $id); + $db->setQuery($query); + + $params = $db->loadResult(); + + if (empty($params)) + { + $params = '{}'; + } + + return $params; + } +} + +class AdvancedModules +{ + static $current_module = null; + + public static function getCurrentModule() + { + return self::$current_module; + } + + public static function setCurrentModule($module) + { + self::$current_module = $module; + } +} diff --git a/deployed/regularlabs/plugins/system/advancedmodules/src/Helpers/advancedmodulehelper_legacy.php b/deployed/regularlabs/plugins/system/advancedmodules/src/Helpers/advancedmodulehelper_legacy.php new file mode 100644 index 00000000..81084630 --- /dev/null +++ b/deployed/regularlabs/plugins/system/advancedmodules/src/Helpers/advancedmodulehelper_legacy.php @@ -0,0 +1,472 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2017 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +jimport('joomla.filesystem.file'); + +use RegularLabs\Library\Conditions as RL_Conditions; +use RegularLabs\Library\Parameters as RL_Parameters; +use RegularLabs\Library\RL_RegEx as RL_RegEx; + +/* + * ModuleHelper methods + */ + +class PlgSystemAdvancedModuleHelper +{ + var $advanced_params = []; + var $mirror_ids = []; + + public function onRenderModule(&$module) + { + // Module already nulled + if (is_null($module)) + { + return false; + } + + // Do nothing if is not frontend + if (!JFactory::getApplication()->isSite()) + { + return false; + } + + // return true if module is empty (this will empty the content) + if ($this->isEmpty($module)) + { + return true; + } + + + return false; + } + + public function isEmpty(&$module) + { + if (!isset($module->content)) + { + return true; + } + + $this->setAdvancedParams($module); + $params = $module->advancedparams; + + // return false if hideempty is off in module params + if (empty($params) || !isset($params->hideempty) || !$params->hideempty) + { + return false; + } + + $config = $this->getConfig(); + + // return false if show_hideempty is off in main config + if (!$config->show_hideempty) + { + return false; + } + + $content = trim($module->content); + + // return true if module is empty + if ($content == '') + { + return true; + } + + // remove html and hidden whitespace + $content = str_replace(chr(194) . chr(160), ' ', $content); + $content = str_replace([' ', ' '], ' ', $content); + // remove comment tags + $content = RL_RegEx::replace('<\!--.*?-->', '', $content); + // remove all closing tags + $content = RL_RegEx::replace(']+>', '', $content); + // remove tags to be ignored + $tags = 'p|div|span|strong|b|em|i|ul|font|br|h[0-9]|fieldset|label|ul|ol|li|table|thead|tbody|tfoot|tr|th|td|form'; + $search = '<(?:' . $tags . ')(?:\s[^>]*)?>'; + + if (RL_RegEx::match($search, $content)) + { + $content = RL_RegEx::replace($search, '', $content); + } + + // return whether content is empty + return (trim($content) == ''); + } + + + public function onPrepareModuleList(&$modules) + { + // return if is not frontend + if (!JFactory::getApplication()->isSite() || empty($modules)) + { + return; + } + + jimport('joomla.filesystem.file'); + + // set params for all loaded modules first + // and make it an associated array (array id = module id) + $new_modules = []; + + foreach ($modules as $id => $module) + { + $this->setAdvancedParams($module); + $new_modules[$module->id] = $module; + } + + $modules = $new_modules; + unset($new_modules); + + foreach ($modules as $id => $module) + { + if (empty($module->id)) + { + continue; + } + + $this->setAdvancedParams($module); + + if ($module->advancedparams === 0) + { + continue; + } + + + $module->reverse = 0; + + if (!isset($module->published)) + { + $module->published = 0; + } + + if ($module->published) + { + $this->setMirrorParams($module); + $this->removeDisabledAssignments($module->advancedparams); + + $assignments = RL_Conditions::getConditionsFromParams($module->advancedparams); + $pass = RL_Conditions::pass($assignments, $module->advancedparams->match_method); + + if (!$pass) + { + $module->published = 0; + } + + if ($module->reverse) + { + $module->published = $module->published ? 0 : 1; + } + } + + $modules[$id] = $module; + } + } + + private function setAdvancedParams(&$module) + { + if (empty($module->id)) + { + return; + } + + if (isset($module->advancedparams) && is_object($module->advancedparams)) + { + return; + } + + if (!isset($module->advancedparams)) + { + $module->advancedparams = $this->getAdvancedParams($module); + } + + $module->advancedparams = json_decode($module->advancedparams); + + if (is_null($module->advancedparams)) + { + $module->advancedparams = (object) []; + } + + if ( + !isset($module->advancedparams->assignto_menuitems) + || isset($module->advancedparams->assignto_urls_selection_sef) + || ( + !is_array($module->advancedparams->assignto_menuitems) + && strpos($module->advancedparams->assignto_menuitems, '|') !== false + ) + ) + { + require_once JPATH_ADMINISTRATOR . '/components/com_advancedmodules/models/module.php'; + $model = new AdvancedModulesModelModule; + + $module->advancedparams = (object) $model->initAssignments($module->id, $module); + } + + $xmlfile_assignments = JPATH_ADMINISTRATOR . '/components/com_advancedmodules/assignments.xml'; + + $module->advancedparams = RL_Parameters::getInstance()->getParams($module->advancedparams, $xmlfile_assignments); + } + + private function setMirrorParams(&$module) + { + $module->mirror_id = $this->getMirrorModuleId($module); + + if (empty($module->mirror_id)) + { + return; + } + + $parameters = RL_Parameters::getInstance(); + + $mirror_id = $module->mirror_id < 0 ? $module->mirror_id * -1 : $module->mirror_id; + + $count = 0; + while ($count++ < 10) + { + if (!$test_mirrorid = $this->getMirrorModuleIdById($mirror_id)) + { + break; + } + + $mirror_id = $test_mirrorid; + } + + if (empty($mirror_id)) + { + return; + } + + $xmlfile_assignments = JPATH_ADMINISTRATOR . '/components/com_advancedmodules/assignments.xml'; + + $module->reverse = $mirror_id < 0; + + if ($mirror_id == $module->id) + { + $empty = (object) []; + $mirror_params = $parameters->getParams($empty, $xmlfile_assignments); + } + else + { + if (isset($modules[$mirror_id])) + { + if (!isset($modules[$mirror_id]->advancedparams)) + { + $modules[$mirror_id]->advancedparams = $this->getAdvancedParamsById($mirror_id); + $modules[$mirror_id]->advancedparams = $parameters->getParams($modules[$mirror_id]->advancedparams, $xmlfile_assignments); + } + + $mirror_params = $modules[$mirror_id]->advancedparams; + } + else + { + $mirror_params = $this->getAdvancedParamsById($mirror_id); + $mirror_params = $parameters->getParams($mirror_params, $xmlfile_assignments); + } + } + + // Keep the advanced settings that shouldn't be mirrored + $settings_to_keep = [ + 'hideempty', 'color', + ]; + + foreach ($settings_to_keep as $key) + { + if (!isset($module->advancedparams->{$key})) + { + continue; + } + + $mirror_params->{$key} = $module->advancedparams->{$key}; + } + + $module->advancedparams = $mirror_params; + } + + private function removeDisabledAssignments(&$params) + { + $config = $this->getConfig(); + + if (!$config->show_assignto_homepage) + { + $params->assignto_homepage = 0; + } + if (!$config->show_assignto_usergrouplevels) + { + $params->assignto_usergrouplevels = 0; + } + if (!$config->show_assignto_date) + { + $params->assignto_date = 0; + } + if (!$config->show_assignto_languages) + { + $params->assignto_languages = 0; + } + if (!$config->show_assignto_templates) + { + $params->assignto_templates = 0; + } + if (!$config->show_assignto_urls) + { + $params->assignto_urls = 0; + } + if (!$config->show_assignto_devices) + { + $params->assignto_devices = 0; + } + if (!$config->show_assignto_os) + { + $params->assignto_os = 0; + } + if (!$config->show_assignto_browsers) + { + $params->assignto_browsers = 0; + } + if (!$config->show_assignto_components) + { + $params->assignto_components = 0; + } + if (!$config->show_assignto_tags) + { + $params->show_assignto_tags = 0; + } + if (!$config->show_assignto_content) + { + $params->assignto_contentpagetypes = 0; + $params->assignto_cats = 0; + $params->assignto_articles = 0; + } + } + + + public function onCreateModuleQuery(&$query) + { + // return if is not frontend + if (!JFactory::getApplication()->isSite()) + { + return; + } + + foreach ($query as $type => $strings) + { + foreach ($strings as $i => $string) + { + if ($type == 'select') + { + $query->{$type}[$i] = str_replace(', mm.menuid', '', $string); + } + else if (strpos($string, 'mm.') !== false || strpos($string, 'm.publish_') !== false) + { + unset($query->{$type}[$i]); + } + } + } + $query->select[] = 'am.params as advancedparams, 0 as menuid, m.publish_up, m.publish_down'; + $query->join[] = '#__advancedmodules as am ON am.moduleid = m.id'; + $query->order = ['m.ordering, m.id']; + } + + private function getConfig() + { + static $instance; + + if (is_object($instance)) + { + return $instance; + } + + $instance = RL_Parameters::getInstance()->getComponentParams('advancedmodules'); + + return $instance; + } + + private function getMirrorModuleId($module) + { + if (isset($module->mirror_id)) + { + return $module->mirror_id; + } + + return $this->getMirrorModuleIdById($module->id); + } + + private function getMirrorModuleIdById($id) + { + if (isset($this->mirror_ids[$id])) + { + return $this->mirror_ids[$id]; + } + + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('a.mirror_id') + ->from('#__advancedmodules AS a') + ->where('a.moduleid = ' . (int) $id); + $db->setQuery($query); + + $this->mirror_ids[$id] = $db->loadResult(); + + return $this->mirror_ids[$id]; + } + + private function getAdvancedParams($module) + { + if (empty($module->id)) + { + return '{}'; + } + + if (isset($this->advanced_params[$module->id])) + { + return $this->advanced_params[$module->id]; + } + + if (isset($module->adv_params)) + { + + $this->advanced_params[$module->id] = $module->adv_params; + + return $this->advanced_params[$module->id]; + } + + return $this->getAdvancedParamsById($module->id); + } + + private function getAdvancedParamsById($id = 0) + { + if (!$id) + { + return '{}'; + } + + if (isset($this->advanced_params[$id])) + { + return $this->advanced_params[$id]; + } + + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('a.params') + ->from('#__advancedmodules AS a') + ->where('a.moduleid = ' . (int) $id); + $db->setQuery($query); + + $params = $db->loadResult(); + if (empty($params)) + { + $params = '{}'; + } + + $this->advanced_params[$id] = $params; + + return $this->advanced_params[$id]; + } +} diff --git a/deployed/regularlabs/plugins/system/advancedmodules/src/Helpers/modulehelper_legacy.php b/deployed/regularlabs/plugins/system/advancedmodules/src/Helpers/modulehelper_legacy.php new file mode 100644 index 00000000..4aa087c9 --- /dev/null +++ b/deployed/regularlabs/plugins/system/advancedmodules/src/Helpers/modulehelper_legacy.php @@ -0,0 +1,667 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2017 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/** + * BASE ON JOOMLA CORE FILE: + * /libraries/cms/module/helper.php (Joomla 3.2) + */ + +/** + * @package Joomla.Libraries + * @subpackage Module + * + * @copyright Copyright (C) 2005 - 2016 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE + */ + +defined('JPATH_PLATFORM') or defined('JPATH_BASE') or die; + +use Joomla\Registry\Registry; + +/** + * Module helper class + * + * @package Joomla.Libraries + * @subpackage Module + * @since 1.5 + */ +abstract class JModuleHelper +{ + /** + * Get module by name (real, eg 'Breadcrumbs' or folder, eg 'mod_breadcrumbs') + * + * @param string $name The name of the module + * @param string $title The title of the module, optional + * + * @return stdClass The Module object + * + * @since 1.5 + */ + public static function &getModule($name, $title = null) + { + $result = null; + $modules =& static::load(); + $total = count($modules); + + for ($i = 0; $i < $total; $i++) + { + // Match the name of the module + if ($modules[$i]->name == $name || $modules[$i]->module == $name) + { + // Match the title if we're looking for a specific instance of the module + if (!$title || $modules[$i]->title == $title) + { + // Found it + $result = &$modules[$i]; + break; + } + } + } + + // If we didn't find it, and the name is mod_something, create a dummy object + if (is_null($result) && substr($name, 0, 4) == 'mod_') + { + $result = (object) [ + 'id' => 0, + 'title' => '', + 'module' => $name, + 'position' => '', + 'content' => '', + 'showtitle' => 0, + 'control' => '', + 'params' => '', + ]; + } + + return $result; + } + + /** + * Get modules by position + * + * @param string $position The position of the module + * + * @return array An array of module objects + * + * @since 1.5 + */ + public static function &getModules($position) + { + $position = strtolower($position); + $result = []; + $input = JFactory::getApplication()->input; + + $modules =& static::load(); + + $total = count($modules); + + for ($i = 0; $i < $total; $i++) + { + if ($modules[$i]->position == $position) + { + $result[] = &$modules[$i]; + } + } + + if (count($result) == 0) + { + if ($input->getBool('tp') && JComponentHelper::getParams('com_templates')->get('template_positions_display')) + { + $result[0] = static::getModule('mod_' . $position); + $result[0]->title = $position; + $result[0]->content = $position; + $result[0]->position = $position; + } + } + + return $result; + } + + /** + * Checks if a module is enabled. A given module will only be returned + * if it meets the following criteria: it is enabled, it is assigned to + * the current menu item or all items, and the user meets the access level + * requirements. + * + * @param string $module The module name + * + * @return boolean See description for conditions. + * + * @since 1.5 + */ + public static function isEnabled($module) + { + $result = static::getModule($module); + + return (!is_null($result) && $result->id !== 0); + } + + /** + * Render the module. + * + * @param object $module A module object. + * @param array $attribs An array of attributes for the module (probably from the XML). + * + * @return string The HTML content of the module output. + * + * @since 1.5 + */ + public static function renderModule($module, $attribs = []) + { + static $chrome; + + // Check that $module is a valid module object + if (!is_object($module) || !isset($module->module) || !isset($module->params)) + { + if (JDEBUG) + { + JLog::addLogger(['text_file' => 'jmodulehelper.log.php'], JLog::ALL, ['modulehelper']); + JLog::add('JModuleHelper::renderModule($module) expects a module object', JLog::DEBUG, 'modulehelper'); + } + + return; + } + + if (JDEBUG) + { + JProfiler::getInstance('Application')->mark('beforeRenderModule ' . $module->module . ' (' . $module->title . ')'); + } + + $app = JFactory::getApplication(); + + // Record the scope. + $scope = $app->scope; + + // Set scope to component name + $app->scope = $module->module; + + // Get module parameters + $params = new Registry; + $params->loadString($module->params); + + // Get the template + $template = $app->getTemplate(); + + // Get module path + $module->module = preg_replace('/[^A-Z0-9_\.-]/i', '', $module->module); + $path = JPATH_BASE . '/modules/' . $module->module . '/' . $module->module . '.php'; + + // Load the module + if (file_exists($path)) + { + $lang = JFactory::getLanguage(); + + // 1.5 or Core then 1.6 3PD + $lang->load($module->module, JPATH_BASE, null, false, true) + || $lang->load($module->module, dirname($path), null, false, true); + + $content = ''; + ob_start(); + include $path; + $module->content = ob_get_contents() . $content; + ob_end_clean(); + } + + // Load the module chrome functions + if (!$chrome) + { + $chrome = []; + } + + include_once JPATH_THEMES . '/system/html/modules.php'; + $chromePath = JPATH_THEMES . '/' . $template . '/html/modules.php'; + + if (!isset($chrome[$chromePath])) + { + if (file_exists($chromePath)) + { + include_once $chromePath; + } + + $chrome[$chromePath] = true; + } + + // Check if the current module has a style param to override template module style + $paramsChromeStyle = $params->get('style'); + + if ($paramsChromeStyle) + { + $attribs['style'] = preg_replace('/^(system|' . $template . ')\-/i', '', $paramsChromeStyle); + } + + // Make sure a style is set + if (!isset($attribs['style'])) + { + $attribs['style'] = 'none'; + } + + // Dynamically add outline style + if ($app->input->getBool('tp') && JComponentHelper::getParams('com_templates')->get('template_positions_display')) + { + $attribs['style'] .= ' outline'; + } + + // Do 3rd party stuff to manipulate module content + // onRenderModule is allowed to alter the $module, $attribs + // and may return a boolean. + // true=remove, any other value = keep. + // $result holds an array of booleans, 1 from each plugin. + // we ditch the module if any of them = true. + $result = $app->triggerEvent('onRenderModule', [&$module, &$attribs]); + if (!is_array($result)) + { + $result = [$result]; + } + if (array_search(true, $result, true) !== false) + { + return ''; + } + + foreach (explode(' ', $attribs['style']) as $style) + { + $chromeMethod = 'modChrome_' . $style; + + // Apply chrome and render module + if (function_exists($chromeMethod)) + { + $module->style = $attribs['style']; + + ob_start(); + $chromeMethod($module, $params, $attribs); + $module->content = ob_get_contents(); + ob_end_clean(); + } + } + + // Revert the scope + $app->scope = $scope; + + if (JDEBUG) + { + JProfiler::getInstance('Application')->mark('afterRenderModule ' . $module->module . ' (' . $module->title . ')'); + } + + return $module->content; + } + + /** + * Get the path to a layout for a module + * + * @param string $module The name of the module + * @param string $layout The name of the module layout. If alternative layout, in the form template:filename. + * + * @return string The path to the module layout + * + * @since 1.5 + */ + public static function getLayoutPath($module, $layout = 'default') + { + $template = JFactory::getApplication()->getTemplate(); + $defaultLayout = $layout; + + if (strpos($layout, ':') !== false) + { + // Get the template and file name from the string + $temp = explode(':', $layout); + $template = ($temp[0] == '_') ? $template : $temp[0]; + $layout = $temp[1]; + $defaultLayout = ($temp[1]) ? $temp[1] : 'default'; + } + + // Build the template and base path for the layout + $tPath = JPATH_THEMES . '/' . $template . '/html/' . $module . '/' . $layout . '.php'; + $bPath = JPATH_BASE . '/modules/' . $module . '/tmpl/' . $defaultLayout . '.php'; + $dPath = JPATH_BASE . '/modules/' . $module . '/tmpl/default.php'; + + // Do 3rd party stuff to detect layout path for the module + // onGetLayoutPath should return the path to the $layout of $module or false + // $results holds an array of results returned from plugins, 1 from each plugin. + // if a path to the $layout is found and it is a file, return that path + $app = JFactory::getApplication(); + $result = $app->triggerEvent('onGetLayoutPath', [$module, $layout]); + if (is_array($result)) + { + foreach ($result as $path) + { + if ($path !== false && is_file($path)) + { + return $path; + } + } + } + + // If the template has a layout override use it + if (file_exists($tPath)) + { + return $tPath; + } + + if (file_exists($bPath)) + { + return $bPath; + } + + return $dPath; + } + + /** + * Load published modules. + * + * @return array + * + * @since 1.5 + * @deprecated 4.0 Use JModuleHelper::load() instead + */ + protected static function &_load() + { + return static::load(); + } + + /** + * Load published modules. + * + * @return array + * + * @since 3.2 + */ + protected static function &load() + { + static $clean; + + if (isset($clean)) + { + $clean = array_values($clean); + + return $clean; + } + + $app = JFactory::getApplication(); + $Itemid = $app->input->getInt('Itemid'); + $user = JFactory::getUser(); + $groups = implode(',', $user->getAuthorisedViewLevels()); + $lang = JFactory::getLanguage()->getTag(); + $clientId = (int) $app->getClientId(); + + $db = JFactory::getDbo(); + $date = JFactory::getDate(); + $now = $date->toSql(); + $nullDate = $db->getNullDate(); + + $query = (object) []; + $query->select = []; + $query->from = []; + $query->join = []; + $query->where = []; + $query->order = []; + + $query->select[] = 'm.published, m.id, m.title, m.module, m.position, m.content, m.showtitle, m.params, mm.menuid'; + $query->from[] = '#__modules AS m'; + $query->join[] = '#__modules_menu AS mm ON mm.moduleid = m.id'; + $query->join[] = '#__extensions AS e ON e.element = m.module AND e.client_id = m.client_id'; + + $query->where[] = '(mm.menuid = ' . (int) $Itemid . ' OR mm.menuid <= 0)'; + + $query->where[] = 'm.published = 1'; + + $query->where[] = 'e.enabled = 1'; + + $query->where[] = 'm.client_id = ' . $clientId; + $query->where[] = 'm.access IN (' . $groups . ')'; + + $query->where[] = '(m.publish_up = ' . $db->quote($nullDate) . ' OR m.publish_up <= ' . $db->quote($now) . ')'; + $query->where[] = '(m.publish_down = ' . $db->quote($nullDate) . ' OR m.publish_down >= ' . $db->quote($now) . ')'; + + // Filter by language + if ($app->isSite() && $app->getLanguageFilter()) + { + $query->where[] = 'm.language IN (' . $db->quote($lang) . ',' . $db->quote('*') . ')'; + } + + $query->order[] = 'm.position, m.ordering'; + + // Do 3rd party stuff to change query + $app->triggerEvent('onCreateModuleQuery', [&$query]); + + $q = $db->getQuery(true); + // convert array object to query object + foreach ($query as $type => $strings) + { + foreach ($strings as $string) + { + if ($type == 'join') + { + $q->{$type}('LEFT', $string); + } + else + { + $q->{$type}($string); + } + } + } + + // Set the query + $db->setQuery($q); + + try + { + $modules = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + JLog::add(JText::sprintf('JLIB_APPLICATION_ERROR_MODULE_LOAD', $e->getMessage()), JLog::WARNING, 'jerror'); + + return []; + } + + // Apply negative selections and eliminate duplicates + $Itemid = JFactory::getApplication()->input->getInt('Itemid'); + $negId = $Itemid ? -(int) $Itemid : false; + $clean = []; + $dupes = []; + + foreach ($modules as $i => $module) + { + // The module is excluded if there is an explicit prohibition + $negHit = ($negId === (int) $module->menuid); + + if (isset($dupes[$module->id])) + { + // If this item has been excluded, keep the duplicate flag set, + // but remove any item from the modules array. + if ($negHit) + { + unset($clean[$module->id]); + } + + continue; + } + + $dupes[$module->id] = true; + + // Only accept modules without explicit exclusions. + if ($negHit) + { + continue; + } + + $module->name = substr($module->module, 4); + $module->style = null; + $module->position = strtolower($module->position); + + $clean[$module->id] = $module; + } + + unset($dupes); + + // Do 3rd party stuff to manipulate module array. + // Any plugins using this architecture may make alterations to the referenced $modules array. + // To remove items you can do unset($modules[n]) or $modules[n]->published = false. + + // "onPrepareModuleList" may alter or add $modules, and does not need to return anything. + // This should be used for module addition/deletion that the user would expect to happen at an + // early stage. + $app->triggerEvent('onPrepareModuleList', [&$clean]); + + // "onAlterModuleList" may alter or add $modules, and does not need to return anything. + $app->triggerEvent('onAlterModuleList', [&$clean]); + + // "onPostProcessModuleList" allows a plugin to perform actions like parameter changes + // on the completed list of modules and is guaranteed to occur *after* + // the earlier plugins. + $app->triggerEvent('onPostProcessModuleList', [&$clean]); + + // Remove any that were marked as disabled during the preceding steps + foreach ($clean as $id => $module) + { + if (!isset($module->published) || $module->published == 0) + { + unset($clean[$id]); + } + } + + // Return to simple indexing that matches the query order. + $clean = array_values($clean); + + return $clean; + } + + /** + * Module cache helper + * + * Caching modes: + * To be set in XML: + * 'static' One cache file for all pages with the same module parameters + * 'oldstatic' 1.5 definition of module caching, one cache file for all pages + * with the same module id and user aid, + * 'itemid' Changes on itemid change, to be called from inside the module: + * 'safeuri' Id created from $cacheparams->modeparams array, + * 'id' Module sets own cache id's + * + * @param object $module Module object + * @param object $moduleparams Module parameters + * @param object $cacheparams Module cache parameters - id or url parameters, depending on the module cache mode + * + * @return string + * + * @see JFilterInput::clean() + * @since 1.6 + */ + public static function moduleCache($module, $moduleparams, $cacheparams) + { + if (!isset($cacheparams->modeparams)) + { + $cacheparams->modeparams = null; + } + + if (!isset($cacheparams->cachegroup)) + { + $cacheparams->cachegroup = $module->module; + } + + $user = JFactory::getUser(); + $cache = JFactory::getCache($cacheparams->cachegroup, 'callback'); + $conf = JFactory::getConfig(); + + // Turn cache off for internal callers if parameters are set to off and for all logged in users + if ($moduleparams->get('owncache', null) === '0' || $conf->get('caching') == 0 || $user->get('id')) + { + $cache->setCaching(false); + } + + // Module cache is set in seconds, global cache in minutes, setLifeTime works in minutes + $cache->setLifeTime($moduleparams->get('cache_time', $conf->get('cachetime') * 60) / 60); + + $wrkaroundoptions = ['nopathway' => 1, 'nohead' => 0, 'nomodules' => 1, 'modulemode' => 1, 'mergehead' => 1]; + + $wrkarounds = true; + $view_levels = md5(serialize($user->getAuthorisedViewLevels())); + + switch ($cacheparams->cachemode) + { + case 'id': + $ret = $cache->get( + [$cacheparams->class, $cacheparams->method], + $cacheparams->methodparams, + $cacheparams->modeparams, + $wrkarounds, + $wrkaroundoptions + ); + break; + + case 'safeuri': + $secureid = null; + + if (is_array($cacheparams->modeparams)) + { + $input = JFactory::getApplication()->input; + $uri = $input->getArray(); + $safeuri = (object) []; + $noHtmlFilter = JFilterInput::getInstance(); + + foreach ($cacheparams->modeparams as $key => $value) + { + // Use int filter for id/catid to clean out spamy slugs + if (isset($uri[$key])) + { + $safeuri->$key = $noHtmlFilter->clean($uri[$key], $value); + } + } + } + + $secureid = md5(serialize([$safeuri, $cacheparams->method, $moduleparams])); + $ret = $cache->get( + [$cacheparams->class, $cacheparams->method], + $cacheparams->methodparams, + $module->id . $view_levels . $secureid, + $wrkarounds, + $wrkaroundoptions + ); + break; + + case 'static': + $ret = $cache->get( + [ + $cacheparams->class, + $cacheparams->method, + ], + $cacheparams->methodparams, + $module->module . md5(serialize($cacheparams->methodparams)), + $wrkarounds, + $wrkaroundoptions + ); + break; + + // Provided for backward compatibility, not really useful. + case 'oldstatic': + $ret = $cache->get( + [$cacheparams->class, $cacheparams->method], + $cacheparams->methodparams, + $module->id . $view_levels, + $wrkarounds, + $wrkaroundoptions + ); + break; + + case 'itemid': + default: + $ret = $cache->get( + [$cacheparams->class, $cacheparams->method], + $cacheparams->methodparams, + $module->id . $view_levels . JFactory::getApplication()->input->getInt('Itemid', null), + $wrkarounds, + $wrkaroundoptions + ); + break; + } + + return $ret; + } +} diff --git a/deployed/regularlabs/plugins/system/advancedmodules/src/ModuleHelper.php b/deployed/regularlabs/plugins/system/advancedmodules/src/ModuleHelper.php new file mode 100644 index 00000000..63b54414 --- /dev/null +++ b/deployed/regularlabs/plugins/system/advancedmodules/src/ModuleHelper.php @@ -0,0 +1,29 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Plugin\System\AdvancedModules; + +defined('_JEXEC') or die; + +use JFactory; +use PlgSystemAdvancedModuleHelper; + +class ModuleHelper +{ + public static function registerEvents() + { + require_once __DIR__ . '/Helpers/advancedmodulehelper.php'; + $class = new PlgSystemAdvancedModuleHelper; + + JFactory::getApplication()->registerEvent('onRenderModule', [$class, 'onRenderModule']); + JFactory::getApplication()->registerEvent('onPrepareModuleList', [$class, 'onPrepareModuleList']); + } +} diff --git a/deployed/regularlabs/plugins/system/advancedmodules/src/Params.php b/deployed/regularlabs/plugins/system/advancedmodules/src/Params.php new file mode 100644 index 00000000..19ca9419 --- /dev/null +++ b/deployed/regularlabs/plugins/system/advancedmodules/src/Params.php @@ -0,0 +1,35 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Plugin\System\AdvancedModules; + +defined('_JEXEC') or die; + +use RegularLabs\Library\Parameters as RL_Parameters; + +class Params +{ + protected static $params = null; + + public static function get() + { + if ( ! is_null(self::$params)) + { + return self::$params; + } + + $params = RL_Parameters::getInstance()->getComponentParams('advancedmodules'); + + self::$params = $params; + + return self::$params; + } +} diff --git a/deployed/regularlabs/plugins/system/advancedmodules/src/Plugin.php b/deployed/regularlabs/plugins/system/advancedmodules/src/Plugin.php new file mode 100644 index 00000000..b2a20878 --- /dev/null +++ b/deployed/regularlabs/plugins/system/advancedmodules/src/Plugin.php @@ -0,0 +1,379 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +/* + * This class is used as template (extend) for most Regular Labs plugins + * This class is not placed in the Regular Labs Library as a re-usable class because + * it also needs to be working when the Regular Labs Library is not installed + */ + +namespace RegularLabs\Plugin\System\AdvancedModules; + +defined('_JEXEC') or die; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +use JFactory; +use JInstaller; +use JPlugin; +use JPluginHelper; +use JText; +use ReflectionMethod; +use RegularLabs\Library\Document as RL_Document; +use RegularLabs\Library\Language as RL_Language; +use RegularLabs\Library\Protect as RL_Protect; + +class Plugin extends JPlugin +{ + public $_alias = ''; + public $_title = ''; + public $_lang_prefix = ''; + + public $_has_tags = false; + public $_enable_in_frontend = true; + public $_enable_in_admin = false; + public $_can_disable_by_url = true; + public $_disable_on_components = false; + public $_protected_formats = []; + public $_page_types = []; + + private $_init = false; + private $_pass = null; + private $_helper = null; + + protected function run() + { + if ( ! $this->passChecks()) + { + return false; + } + + if ( ! $this->getHelper()) + { + return false; + } + + $caller = debug_backtrace()[1]; + + if (empty($caller)) + { + return false; + } + + $event = $caller['function']; + + if ( ! method_exists($this->_helper, $event)) + { + return false; + } + + $reflect = new ReflectionMethod($this->_helper, $event); + $parameters = $reflect->getParameters(); + + $arguments = []; + + // Check if arguments should be passed as reference or not + foreach ($parameters as $count => $parameter) + { + if ($parameter->isPassedByReference()) + { + $arguments[] = &$caller['args'][$count]; + continue; + } + $arguments[] = $caller['args'][$count]; + } + + return call_user_func_array([$this->_helper, $event], $arguments); + } + + /** + * Create the helper object + * + * @return object|null The plugins helper object + */ + private function getHelper() + { + // Already initialized, so return + if ($this->_init) + { + return $this->_helper; + } + + $this->_init = true; + + RL_Language::load('plg_' . $this->_type . '_' . $this->_name); + + $this->init(); + + $this->_helper = new Helper; + + return $this->_helper; + } + + private function passChecks() + { + if ( ! is_null($this->_pass)) + { + return $this->_pass; + } + + $this->_pass = false; + + if ( ! $this->isFrameworkEnabled()) + { + return false; + } + + if ( ! self::passPageTypes()) + { + return false; + } + + // allow in frontend? + if ( ! $this->_enable_in_frontend + && ! RL_Document::isAdmin()) + { + return false; + } + + // allow in admin? + if ( ! $this->_enable_in_admin + && RL_Document::isAdmin() + && ( ! isset(Params::get()->enable_admin) || ! Params::get()->enable_admin)) + { + return false; + } + + // disabled by url? + if ($this->_can_disable_by_url + && RL_Protect::isDisabledByUrl($this->_alias)) + { + return false; + } + + // disabled by component? + if ($this->_disable_on_components + && RL_Protect::isRestrictedComponent(isset(Params::get()->disabled_components) ? Params::get()->disabled_components : [], 'component')) + { + return false; + } + + // restricted page? + if (RL_Protect::isRestrictedPage($this->_has_tags, $this->_protected_formats)) + { + return false; + } + + if ( ! $this->extraChecks()) + { + return false; + } + + $this->_pass = true; + + return true; + } + + public function passPageTypes() + { + if (empty($this->_page_types)) + { + return true; + } + + if (in_array('*', $this->_page_types)) + { + return true; + } + + if (empty(JFactory::$document)) + { + return true; + } + + if (RL_Document::isFeed()) + { + return in_array('feed', $this->_page_types); + } + + if (RL_Document::isPDF()) + { + return in_array('pdf', $this->_page_types); + } + + $page_type = JFactory::getDocument()->getType(); + + if (in_array($page_type, $this->_page_types)) + { + return true; + } + + return false; + } + + public function extraChecks() + { + return true; + } + + public function init() + { + return; + } + + /** + * Check if the Regular Labs Library is enabled + * + * @return bool + */ + private function isFrameworkEnabled() + { + if ( ! defined('REGULAR_LABS_LIBRARY_ENABLED')) + { + $this->setIsFrameworkEnabled(); + } + + if ( ! REGULAR_LABS_LIBRARY_ENABLED) + { + $this->throwError('REGULAR_LABS_LIBRARY_NOT_ENABLED'); + } + + return REGULAR_LABS_LIBRARY_ENABLED; + } + + /** + * Set the define with whether the Regular Labs Library is enabled + */ + private function setIsFrameworkEnabled() + { + // Return false if Regular Labs Library is not installed + if ( ! $this->isFrameworkInstalled()) + { + define('REGULAR_LABS_LIBRARY_ENABLED', false); + + return; + } + + if ( ! JPluginHelper::isEnabled('system', 'regularlabs')) + { + $this->throwError('REGULAR_LABS_LIBRARY_NOT_ENABLED'); + + define('REGULAR_LABS_LIBRARY_ENABLED', false); + + return; + } + + define('REGULAR_LABS_LIBRARY_ENABLED', true); + } + + /** + * Check if the Regular Labs Library is installed + * + * @return bool + */ + private function isFrameworkInstalled() + { + if ( ! defined('REGULAR_LABS_LIBRARY_INSTALLED')) + { + $this->setIsFrameworkInstalled(); + } + + switch (REGULAR_LABS_LIBRARY_INSTALLED) + { + case 'outdated': + $this->throwError('REGULAR_LABS_LIBRARY_OUTDATED'); + + return false; + + case 'no': + $this->throwError('REGULAR_LABS_LIBRARY_NOT_INSTALLED'); + + return false; + + case 'yes': + default: + return true; + } + } + + /** + * set the define with whether the Regular Labs Library is installed + */ + private function setIsFrameworkInstalled() + { + if ( + ! is_file(JPATH_PLUGINS . '/system/regularlabs/regularlabs.xml') + || ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php') + ) + { + define('REGULAR_LABS_LIBRARY_INSTALLED', 'no'); + + return; + } + + $plugin = JInstaller::parseXMLInstallFile(JPATH_PLUGINS . '/system/regularlabs/regularlabs.xml'); + $library = JInstaller::parseXMLInstallFile(JPATH_LIBRARIES . '/regularlabs/regularlabs.xml'); + + if (empty($plugin) || empty($library)) + { + define('REGULAR_LABS_LIBRARY_INSTALLED', 'no'); + + return; + } + + if (version_compare($plugin['version'], '18.7.10792', '<') + || version_compare($library['version'], '18.7.10792', '<')) + { + define('REGULAR_LABS_LIBRARY_INSTALLED', 'outdated'); + + return; + } + + define('REGULAR_LABS_LIBRARY_INSTALLED', 'yes'); + } + + /** + * Place an error in the message queue + */ + private function throwError($error) + { + // Return if page is not an admin page or the admin login page + if ( + ! JFactory::getApplication()->isClient('administrator') + || JFactory::getUser()->get('guest') + ) + { + return; + } + + // load the admin language file + JFactory::getLanguage()->load('plg_' . $this->_type . '_' . $this->_name, JPATH_PLUGINS . '/' . $this->_type . '/' . $this->_name); + + $text = JText::sprintf($this->_lang_prefix . '_' . $error, JText::_($this->_title)); + $text = JText::_($text) . ' ' . JText::sprintf($this->_lang_prefix . '_EXTENSION_CAN_NOT_FUNCTION', JText::_($this->_title)); + + // Check if message is not already in queue + $messagequeue = JFactory::getApplication()->getMessageQueue(); + foreach ($messagequeue as $message) + { + if ($message['message'] == $text) + { + return; + } + } + + JFactory::getApplication()->enqueueMessage($text, 'error'); + } +} + diff --git a/deployed/regularlabs/plugins/system/advancedmodules/vendor/autoload.php b/deployed/regularlabs/plugins/system/advancedmodules/vendor/autoload.php new file mode 100644 index 00000000..945be0e2 --- /dev/null +++ b/deployed/regularlabs/plugins/system/advancedmodules/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 = []; + private $prefixDirsPsr4 = []; + private $fallbackDirsPsr4 = []; + + // PSR-0 + private $prefixesPsr0 = []; + private $fallbackDirsPsr0 = []; + + private $useIncludePath = false; + private $classMap = []; + private $classMapAuthoritative = false; + private $missingClasses = []; + private $apcuPrefix; + + public function getPrefixes() + { + if ( ! empty($this->prefixesPsr0)) + { + return call_user_func_array('array_merge', $this->prefixesPsr0); + } + + return []; + } + + 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') && ini_get('apc.enabled') ? $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([$this, 'loadClass'], true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister([$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])) + { + foreach ($this->prefixDirsPsr4[$search] as $dir) + { + $length = $this->prefixLengthsPsr4[$first][$search]; + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) + { + 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/deployed/regularlabs/plugins/system/advancedmodules/vendor/composer/LICENSE b/deployed/regularlabs/plugins/system/advancedmodules/vendor/composer/LICENSE new file mode 100644 index 00000000..f27399a0 --- /dev/null +++ b/deployed/regularlabs/plugins/system/advancedmodules/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/deployed/regularlabs/plugins/system/advancedmodules/vendor/composer/autoload_classmap.php b/deployed/regularlabs/plugins/system/advancedmodules/vendor/composer/autoload_classmap.php new file mode 100644 index 00000000..d708c05f --- /dev/null +++ b/deployed/regularlabs/plugins/system/advancedmodules/vendor/composer/autoload_classmap.php @@ -0,0 +1,9 @@ + [$baseDir . '/src'], +]; diff --git a/deployed/regularlabs/plugins/system/advancedmodules/vendor/composer/autoload_real.php b/deployed/regularlabs/plugins/system/advancedmodules/vendor/composer/autoload_real.php new file mode 100644 index 00000000..8d3b928d --- /dev/null +++ b/deployed/regularlabs/plugins/system/advancedmodules/vendor/composer/autoload_real.php @@ -0,0 +1,60 @@ += 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\ComposerStaticInit0607aff10648ef74c8ea6dd76ad3cc2d::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); + + return $loader; + } +} diff --git a/deployed/regularlabs/plugins/system/advancedmodules/vendor/composer/autoload_static.php b/deployed/regularlabs/plugins/system/advancedmodules/vendor/composer/autoload_static.php new file mode 100644 index 00000000..5c18e8c4 --- /dev/null +++ b/deployed/regularlabs/plugins/system/advancedmodules/vendor/composer/autoload_static.php @@ -0,0 +1,30 @@ + + [ + 'RegularLabs\\Plugin\\System\\AdvancedModules\\' => 42, + ], + ]; + + public static $prefixDirsPsr4 = [ + 'RegularLabs\\Plugin\\System\\AdvancedModules\\' => + [ + 0 => __DIR__ . '/../..' . '/src', + ], + ]; + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInit0607aff10648ef74c8ea6dd76ad3cc2d::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit0607aff10648ef74c8ea6dd76ad3cc2d::$prefixDirsPsr4; + }, null, ClassLoader::class); + } +} diff --git a/deployed/regularlabs/plugins/system/advancedmodules/vendor/composer/installed.json b/deployed/regularlabs/plugins/system/advancedmodules/vendor/composer/installed.json new file mode 100644 index 00000000..fe51488c --- /dev/null +++ b/deployed/regularlabs/plugins/system/advancedmodules/vendor/composer/installed.json @@ -0,0 +1 @@ +[] diff --git a/deployed/regularlabs/plugins/system/modals/language/en-GB/en-GB.plg_system_modals.ini b/deployed/regularlabs/plugins/system/modals/language/en-GB/en-GB.plg_system_modals.ini new file mode 100644 index 00000000..c2c21b73 --- /dev/null +++ b/deployed/regularlabs/plugins/system/modals/language/en-GB/en-GB.plg_system_modals.ini @@ -0,0 +1,219 @@ +;; @package Modals +;; @version 9.13.0 +;; +;; @author Peter van Westen +;; @link http://www.regularlabs.com +;; @copyright Copyright © 2018 Regular Labs All Rights Reserved +;; @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL +;; +;; @translate Want to help with translations? See: https://www.regularlabs.com/translate + +PLG_SYSTEM_MODALS="System - Regular Labs - Modals" +PLG_SYSTEM_MODALS_DESC="Modals - make modal popups in Joomla!" +MODALS="Modals" + +INSERT_MODAL="Insert Modal" +MODALS_DESC="With Modals you can make modal popup links anywhere in Joomla!

The syntax simply looks like:
{modal url/of/the/page/to/open}Link text{/modal}" + +MDL_EXTENSION_CAN_NOT_FUNCTION="[[%1:extension name%]] cannot function." +MDL_REGULAR_LABS_LIBRARY_NOT_ENABLED="Regular Labs Library plugin is not enabled." +MDL_REGULAR_LABS_LIBRARY_NOT_INSTALLED="Regular Labs Library plugin is not installed." +MDL_REGULAR_LABS_LIBRARY_OUTDATED="Regular Labs Library plugin is outdated. Try to re-install [[%1:extension name%]]." + +MDL_ADD_REDIRECT="Add Redirect Script" +MDL_ADD_REDIRECT_DESC="If selected, a redirect script will be added to the modal pages that will make the page reload as a normal page when not opened in a modal window." +MDL_ARTICLE_DESC="Select an article you want to open in the modal popup." +MDL_ARTICLE_TYPE="Use Title or ID" +MDL_ARTICLE_TYPE_DESC="Select whether to use the article Title or ID in the modal tag." +MDL_AS_DESCRIPTION="As Description" +MDL_AS_TITLE="As Title" +MDL_AUTO_CORRECT_SIZE="Auto-Correct Resize" +MDL_AUTO_CORRECT_SIZE_DELAY="Auto-Resizing Delay (ms)" +MDL_AUTO_CORRECT_SIZE_DELAY_DESC="The Delay (in milliseconds) after which the modal should do the auto-correct resize. Increase this value if you have (slower) scripts causing changes in the modal content dimentions." +MDL_AUTO_CORRECT_SIZE_DESC="If selected, the modal popup will do an extra resize after the content in the modal is loaded. This will fix sizing issues with certain types of content." +MDL_AUTO_GALLERY="Auto Gallery" +MDL_AUTO_GROUP="Auto Group" +MDL_AUTO_GROUP_DESC="Select to automatically group certain filetypes to create series / galleries." +MDL_AUTO_GROUP_FILTER="URL/File Filter" +MDL_AUTO_GROUP_FILTER_DESC="The filter (Regular Expression) used to define which URLs/file types to group automatically." +MDL_AUTO_TITLES="Auto Titles" +MDL_AUTO_TITLES_DESC="If selected, the title will automatically be set based on the file name. This only applies to media files." +MDL_AUTOCLOSE="Auto-close (ms)" +MDL_AUTOCLOSE_DESC="Set the time (in milliseconds) after which the modal should close automatically. Leave empty to disable the auto-close." +MDL_AUTOCONVERT="Auto-Convert" +MDL_AUTOCONVERT_CLASSNAMES_DESC="If selected, all links with one of the given classnames will be converted to modal popup links." +MDL_AUTOCONVERT_CLASSNAMES_IMAGES_DESC="If selected, all images with one of the given classnames will be converted to modal popup links." +MDL_AUTOCONVERT_FILETYPES_DESC="If selected, all links to files that match one of the given filetypes will be converted to modal popup links." +MDL_AUTOCONVERT_URLS_DESC="If selected, all links that match the URL selection will be converted to modal popup links." +MDL_CASE_TITLES="Case Auto Titles" +MDL_CASE_TITLES_DESC="Select the way the auto title should be cased." +MDL_CLASSNAMES="Classnames" +MDL_CLASSNAMES_DESC="A comma separated list of classnames. Links that have any of the defined classnames will be converted to modal popup links." +MDL_CLASSNAMES_IMAGES_DESC="A comma separated list of classnames. Images that have any of the defined classnames will be converted to a modal popup gallery." +MDL_CONTENT_DESC="Enter the content you want to open in the modal popup." +MDL_CONTENT_TAG="Modal Content Tag" +MDL_CONTENT_TAG_DESC="The word used for the modal content tags used to define content for modal links that open by id.

You can change the word if you are using another plugin that uses this tag syntax." +MDL_CSS_CLASS_LINK="CSS Class Link" +MDL_CSS_CLASS_LINK_DESC="An optional CSS Classname to add to the Modal link element. This can be used for styling purposes." +MDL_CSS_CLASS_MODAL="CSS Class Modal" +MDL_CSS_CLASS_MODAL_DESC="An optional CSS Classname to add to the Modal popup element. This can be used for styling purposes." +MDL_DIMENSION_DESC="Set the fixed dimension. In pixels (ie 500) or percentage (ie 80%). Leave empty to attempt auto-sizing." +MDL_DIMENSIONS="Dimensions" +MDL_DISABLE_BACKGROUND_SCROLLING="Disable Background Scrolling" +MDL_DISABLE_BACKGROUND_SCROLLING_DESC="Select to disable the main window from scrolling along when the modal is opened." +MDL_DISABLE_ON_MOBILE="Disable on Mobile" +MDL_DISABLE_ON_MOBILE_DESC="Select to open links normally (not in modal windows) on narrow screens." +MDL_DISABLE_ON_MOBILE_SPLASH="Disable Pageload Popups on Mobile" +MDL_DISABLE_ON_MOBILE_SPLASH_DESC="Select to disable modal popups entirely for modals set to open on pageload." +MDL_ELASTIC="Elastic" +MDL_ENABLE_ARROW_KEYS="Enable Arrow Keys" +MDL_ENABLE_ARROW_KEYS_DESC="If selected, enables the left and right arrow keys from navigating between the items in a group." +MDL_ENABLE_CLOSE_BUTTON="Close Button" +MDL_ENABLE_CLOSE_BUTTON_DESC="If selected, enables the close button." +MDL_ENABLE_COUNTDOWN="Enable Countdown Bar" +MDL_ENABLE_COUNTDOWN_DESC="If selected, there will be a countdown bar at the top of the modal when using the autoclose feature." +MDL_ENABLE_ESC_KEY="Enable ESC Key" +MDL_ENABLE_ESC_KEY_DESC="If selected, enables closing the modal on 'esc' key press." +MDL_EXCLUDE_URLS="Exclude URLs" +MDL_EXCLUDE_URLS_DESC="A comma separated list of (part of) URLs to exclude." +MDL_EXISTING_LINK="Existing Links" +MDL_EXTERNAL_DIMENSION_DESC="Set the fixed dimension for external URLs. In pixels (ie 500) or percentage (ie 80%)." +MDL_EXTERNAL_HEIGHT="Height External Pages" +MDL_EXTERNAL_LINKS="External Links" +MDL_EXTERNAL_LINKS_DESC="If selected, all links to external sites will be converted to modal popup links." +MDL_EXTERNAL_WIDTH="Width External Pages" +MDL_FADE="Fade" +MDL_FAST_IFRAME="Fast Iframe" +MDL_FAST_IFRAME_DESC="If deselected, the loading graphic removal and onComplete event will be delayed until iframe's content has completely loaded." +MDL_FILETYPES="Filetypes" +MDL_FILETYPES_DESC="A comma separated list of filetypes. Links that point to any of the defined filetypes will be converted to modal popup links." +MDL_FIRST="First (Alphabetically)" +MDL_FIXED="Fixed" +MDL_FIXED_DESC="If selected, the modal will be displayed in a fixed position within the visitor's viewport. This is unlike the default absolute positioning relative to the document." +MDL_GALLERY_CREATE_THUMBS="Create Thumbnails" +MDL_GALLERY_CREATE_THUMBS_DESC="If selected, thumbnails will be automatically created for the gallery images if they do not exist yet. The thumbnails will be created using the given 'Thumbnail Width' value." +MDL_GALLERY_DESC="Enter the path to the folder that contains your gallery images." +MDL_GALLERY_FILTER="File Filter" +MDL_GALLERY_FILTER_DESC="The filter (Regular Expression) used to find the image files in the given gallery folder." +MDL_GALLERY_FIRST="First Image" +MDL_GALLERY_FIRST_DESC="Select what image you want to show as first image in the gallery" +MDL_GALLERY_FIRST_SPECIFIC="Specific First Image" +MDL_GALLERY_FIRST_SPECIFIC_DESC="Enter the file name of the image you want to show first" +MDL_GALLERY_SEPARATOR="Image Separator" +MDL_GALLERY_SEPARATOR_DESC="Set the separator html for the images in the gallery. By default this is a space. Enter {none} to have no spacing between images." +MDL_GALLERY_SHOW_ALL="Show All Gallery Thumbnails" +MDL_GALLERY_SHOW_ALL_DESC="If selected, all thumbnails in the given gallery folder will be automatically shown." +MDL_GALLERY_SLIDESHOW="Slideshow" +MDL_GALLERY_SLIDESHOW_DESC="Select to open the gallery as a slideshow." +MDL_GALLERY_THUMB_DIMENSION_DESC="Set the thumbnail dimension in pixels (ie 80). Leave empty to not force a specific size." +MDL_GALLERY_THUMB_HEIGHT="Thumbnail Height" +MDL_GALLERY_THUMB_QUALITY="Quality" +MDL_GALLERY_THUMB_QUALITY_DESC="The quality of the automatically created thumbnails. A value ranging from 0 (worst quality, smaller file) to 100 (best quality, biggest file)." +MDL_GALLERY_THUMB_SUFFIX="Thumbnail Suffix" +MDL_GALLERY_THUMB_SUFFIX_DESC="The suffix to identify the thumbnail to show as the link. Example with default value '_t': if the main image is 'apple.jpg', then the thumbnail image is 'apple_t.jpg'." +MDL_GALLERY_THUMB_WIDTH="Thumbnail Width" +MDL_GALLERY_THUMBNAIL="Thumbnail" +MDL_GALLERY_THUMBNAIL_DESC="Select which thumbnail image should be shown." +MDL_GROUPS="Groups / Slideshows" +MDL_IFRAME="Open as Iframe" +MDL_IFRAME_DESC="If selected, modals will be opened as iframe by default. This excludes links to media files." +MDL_IFRAME_DESC2="Select to open the modal as an iframe. This excludes links to media files." +MDL_IFRAME_FILES="Iframe File Types" +MDL_IFRAME_FILES_DESC="A comma separated list of file types to always open in iframe mode." +MDL_IMAGE_DESC="Select an image you want to open in the modal popup.
If you want to open an external image, simply use the URL option." +MDL_IMAGES="Images" +MDL_INITIAL_DIMENSION_DESC="Set the initial dimension, prior to any content being loaded. In pixels (ie 500) or percentage (ie 80%)." +MDL_INITIAL_HEIGHT="Initial Height" +MDL_INITIAL_WIDTH="Initial Width" +MDL_INTERNAL_LINKS="Internal Links" +MDL_INTERNAL_LINKS_DESC="If selected, all links to internal sites will be converted to modal popup links." +MDL_LINK_TEXT_HINT="Text for the link" +MDL_LOAD_HEAD="Load scripts/styles" +MDL_LOAD_HEAD_DESC="Select to load the scripts, styles and other document head data in the inline modal content. Only enable when certain functionality/styling isn't working inside the modal windows." +MDL_LOOP="Loop" +MDL_LOOP_DESC="If selected, enables the ability to loop back to the beginning of the group when on the last element." +MDL_LOWERCASE="lowercase" +MDL_MAX_DIMENSION_DESC="Set the maximum dimension for loaded content. In pixels (ie 500) or percentage (ie 80%). Set to 0 for no maximum." +MDL_MAX_HEIGHT="Maximum Height" +MDL_MAX_WIDTH="Maximum Width" +MDL_MEDIA_FILES="Media File Types" +MDL_MEDIA_FILES_DESC="A comma separated list of file types to interpret as media files." +MDL_MOBILE_MAX_WIDTH="Max Width Mobiles" +MDL_MOBILE_MAX_WIDTH_DESC="The maximum width in pixels for which to disable Modals." +MDL_MODALTXT_CLOSE="close" +MDL_MODALTXT_CURRENT="%1$s / %2$s" +MDL_MODALTXT_IMGERROR="This image failed to load." +MDL_MODALTXT_NEXT="next" +MDL_MODALTXT_PREVIOUS="previous" +MDL_MODALTXT_XHRERROR="This content failed to load." +MDL_MORE_SETTINGS="For more available options you can set via the {modal} tag, please see [[%1:start link%]]the Modals Tutorial[[%2:end link%]]." +MDL_ONCE="Once" +MDL_OPACITY="Overlay Opacity" +MDL_OPACITY_DESC="The overlay opacity level. Range: 0 to 1." +MDL_OPEN_COKIE_ID_DESC="Enter an optional ID to append to the cookie name. You can use this when changing settings and want to negate earlier set cookies." +MDL_OPEN_COOKIE_ID="Cookie ID" +MDL_OPEN_COUNT_BASED_ON="Open count based on" +MDL_OPEN_COUNT_BASED_ON_DESC="Select whether to base the open count on the visits on entire website or on specific page (url). The open count is used when using the openOnce, openMin and openMax attributes." +MDL_OPEN_COUNT_TTL="Cookie Lifetime" +MDL_OPEN_COUNT_TTL_DESC="The of lifetime of the cookie (in minutes) used to determine the open count. Set to 0 to have no expiration time, the browser cookie will then be kept till the user removes it manually." +MDL_OPEN_ON_PAGELOAD="Open on Pageload" +MDL_OPEN_ON_PAGELOAD_DESC="Select to open the modal directly on pageload, every time (Yes) or just the first time (Once)." +MDL_OVERLAY_CLOSE="Overlay Close" +MDL_OVERLAY_CLOSE_DESC="If selected, enables closing the modal by clicking on the background overlay." +MDL_PAGE_COOKIES="Page (Cookies)" +MDL_POSITIONING="Positioning" +MDL_POSITIONING_DESC="Controls the positioning of the modal instead of using the default position of being centered in the viewport. In pixels (ie 20) or percentage (ie 10%)." +MDL_PRELOADING="Preloading" +MDL_PRELOADING_DESC="If selected, the 'Next' and 'Previous' content in a group will get preloaded after the current content has finished loading." +MDL_RANDOM="Random" +MDL_REPOSITION="Reposition" +MDL_REPOSITION_DESC="Repositions the modal if the window's resize event is fired." +MDL_RETINA_IMAGE="Retina Image" +MDL_RETINA_IMAGE_DESC="If selected, the modal will scale down the current photo to match the screen's pixel ratio" +MDL_RETINA_IMAGES="Retina Images" +MDL_RETINA_SUFFIX="Retina Suffix" +MDL_RETINA_SUFFIX_DESC="If the device has a high resolution display, the href value will have it's extension extended with this suffix. For example, the default value would change my-photo.jpg to my-photo@2x.jpg" +MDL_RETINA_URL="Retina URL" +MDL_RETINA_URL_DESC="If selected and the device has a high resolution display, the modal will replace the current photo's file extension with the Retina Suffix + extension" +MDL_RETURN_FOCUS="Return Focus" +MDL_RETURN_FOCUS_DESC="If selected, focus will be returned when the modal exits to the element it was launched from." +MDL_SCALE_PHOTOS="Scale Photos" +MDL_SCALE_PHOTOS_DESC="If selected, and if maxWidth, maxHeight, width or height have been defined, the modal will scale photos to fit within the those values." +MDL_SETTINGS_TITLE="Extra Modal Settings" +MDL_SLIDESHOW="Slideshow" +MDL_SLIDESHOW_AUTO="Slideshow Auto" +MDL_SLIDESHOW_AUTO_DESC="If selected, the slideshow will automatically start to play." +MDL_SLIDESHOW_DESC="If selected, adds an automatic slideshow to a content group / gallery." +MDL_SLIDESHOW_SPEED="Slideshow Speed" +MDL_SLIDESHOW_SPEED_DESC="Sets the speed of the slideshow, in milliseconds." +MDL_SPECIFIC="Specific Image" +MDL_SPEED="Speed" +MDL_SPEED_DESC="Sets the speed of the transition, in milliseconds." +MDL_STYLE="Style" +MDL_STYLE_DESC="Select a style to use for the modal popup windows" +MDL_SUB_TEMPLATE="Sub Template" +MDL_SUB_TEMPLATE_DESC="This is the sub template used for the internal pages in the modal popup windows. There will have to be a php file with this name in your templates folder or otherwise in the system templates folder." +MDL_TAG="Modal Tag" +MDL_TAG_DESC="The word used for the modal tags.

You can change the word if you are using another plugin that uses this tag syntax." +MDL_TARGET="Target Blank" +MDL_TARGET_DESC="If selected, all links that have a target="_blank" will be converted to modal popup links." +MDL_TITLE_DESC="An optional title to add to the modal popup." +MDL_TITLECASE="Titlecase (Uppercase All Words)" +MDL_TITLECASE_LOWERCASE_WORDS="Lowercase Words" +MDL_TITLECASE_LOWERCASE_WORDS_DESC="A comma separated list of words of which the first word should be lowercase in the auto titles." +MDL_TITLECASE_SMART="Smart Titlecase (No Uppercasing of Certain Words)" +MDL_TRANSITION="Transition" +MDL_TRANSITION_DESC="The transition type." +MDL_UPPERCASE="UPPERCASE" +MDL_UPPERCASE_FIRST="Uppercase first letter" +MDL_URL_DESC="Enter the URL you wish to open in the modal popup." +MDL_USE_ALT_ATTRIBUTE="Use Alt Attribute" +MDL_USE_ALT_ATTRIBUTE_DESC="Select to use the alt attribute in the image tag as the title or description of the modal popup." +MDL_USE_TITLE_ATTRIBUTE="Use Title Attribute" +MDL_USE_TITLE_ATTRIBUTE_DESC="Select to use the title attribute in the image tag as the title or description of the modal popup." +MDL_VIDEO="Video" +MDL_VIDEO_DESC="Enter the Youtube/Vimeo ID (or url) you want to open in the modal popup" +MDL_VIMEO="Vimeo" +MDL_WEBSITE_COOKIES="Website (Cookies)" +MDL_WEBSITE_SESSION="Website (Session)" +MDL_YOUTUBE="Youtube" diff --git a/deployed/regularlabs/plugins/system/modals/language/en-GB/en-GB.plg_system_modals.sys.ini b/deployed/regularlabs/plugins/system/modals/language/en-GB/en-GB.plg_system_modals.sys.ini new file mode 100644 index 00000000..8e070674 --- /dev/null +++ b/deployed/regularlabs/plugins/system/modals/language/en-GB/en-GB.plg_system_modals.sys.ini @@ -0,0 +1,13 @@ +;; @package Modals +;; @version 9.13.0 +;; +;; @author Peter van Westen +;; @link http://www.regularlabs.com +;; @copyright Copyright © 2018 Regular Labs All Rights Reserved +;; @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL +;; +;; @translate Want to help with translations? See: https://www.regularlabs.com/translate + +PLG_SYSTEM_MODALS="System - Regular Labs - Modals" +PLG_SYSTEM_MODALS_DESC="Modals - make modal popups in Joomla!" +MODALS="Modals" diff --git a/deployed/regularlabs/plugins/system/modals/modal.php b/deployed/regularlabs/plugins/system/modals/modal.php new file mode 100644 index 00000000..0e682bbf --- /dev/null +++ b/deployed/regularlabs/plugins/system/modals/modal.php @@ -0,0 +1,59 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; + +use RegularLabs\Library\Parameters as RL_Parameters; +use RegularLabs\Library\RegEx as RL_RegEx; + +?> +input->get('iframe')) : ?> + language = JFactory::getDocument()->language; + $this->direction = JFactory::getDocument()->direction; + ?> + + + + + + + + + + + + getPluginParams('modals'); + ?> + load_head) : ?> + getHeadData(); + foreach ($headerdata['scripts'] as $file => $type) + { + if ( ! RL_RegEx::match('/jquery(-(noconflict|migrate))?(\.min)?\.js', $file)) + { + continue; + } + + unset($headerdata['scripts'][$file]); + } + $headerdata = JFactory::getDocument()->setHeadData($headerdata); + ?> + + + + + diff --git a/deployed/regularlabs/plugins/system/modals/modals.php b/deployed/regularlabs/plugins/system/modals/modals.php new file mode 100644 index 00000000..f4973f2e --- /dev/null +++ b/deployed/regularlabs/plugins/system/modals/modals.php @@ -0,0 +1,64 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +// Do not instantiate plugin on install pages +// to prevent installation/update breaking because of potential breaking changes +if ( + in_array(JFactory::getApplication()->input->get('option'), ['com_installer', 'com_regularlabsmanager']) + && JFactory::getApplication()->input->get('action') != '' +) +{ + return; +} + +if ( ! is_file(__DIR__ . '/vendor/autoload.php')) +{ + return; +} + +require_once __DIR__ . '/vendor/autoload.php'; + +use RegularLabs\Plugin\System\Modals\Plugin; + +/** + * System Plugin that places a Modals code block into the text + */ +class PlgSystemModals extends Plugin +{ + public $_alias = 'modals'; + public $_title = 'MODALS'; + public $_lang_prefix = 'MDL'; + + public $_has_tags = true; + public $_disable_on_components = true; + + /* + * Below are the events that this plugin uses + * All handling is passed along to the parent run method + */ + public function onContentPrepare() + { + $this->run(); + } + + public function onAfterDispatch() + { + $this->run(); + } + + public function onAfterRender() + { + $this->run(); + } +} + diff --git a/deployed/regularlabs/plugins/system/modals/modals.xml b/deployed/regularlabs/plugins/system/modals/modals.xml new file mode 100644 index 00000000..1f134523 --- /dev/null +++ b/deployed/regularlabs/plugins/system/modals/modals.xml @@ -0,0 +1,323 @@ + + + plg_system_modals + PLG_SYSTEM_MODALS_DESC + 9.13.0 + August 2018 + Regular Labs (Peter van Westen) + info@regularlabs.com + https://www.regularlabs.com + Copyright © 2018 Regular Labs - All Rights Reserved + http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + + script.install.php + + + + https://download.regularlabs.com/updates.xml?e=modals&type=.xml + + + + + modals.php + modal.php + script.install.helper.php + language + src + vendor + + + + css + images + js + less + + + + +
+ + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
diff --git a/deployed/regularlabs/plugins/system/modals/script.install.helper.php b/deployed/regularlabs/plugins/system/modals/script.install.helper.php new file mode 100644 index 00000000..fadac36d --- /dev/null +++ b/deployed/regularlabs/plugins/system/modals/script.install.helper.php @@ -0,0 +1,852 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +class PlgSystemModalsInstallerScriptHelper +{ + public $name = ''; + public $alias = ''; + public $extname = ''; + public $extension_type = ''; + public $plugin_folder = 'system'; + public $module_position = 'status'; + public $client_id = 1; + public $install_type = 'install'; + public $show_message = true; + public $db = null; + public $softbreak = null; + + public function __construct(&$params) + { + $this->extname = $this->extname ?: $this->alias; + $this->db = JFactory::getDbo(); + } + + public function preflight($route, JAdapterInstance $adapter) + { + if ( ! in_array($route, ['install', 'update'])) + { + return true; + } + + JFactory::getLanguage()->load('plg_system_regularlabsinstaller', JPATH_PLUGINS . '/system/regularlabsinstaller'); + + if ($this->show_message && $this->isInstalled()) + { + $this->install_type = 'update'; + } + + if ($this->onBeforeInstall($route) === false) + { + return false; + } + + return true; + } + + public function postflight($route, JAdapterInstance $adapter) + { + $this->removeGlobalLanguageFiles(); + $this->removeUnusedLanguageFiles(); + + JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); + + if ( ! in_array($route, ['install', 'update'])) + { + return true; + } + + $this->fixExtensionNames(); + $this->updateUpdateSites(); + $this->removeAdminCache(); + + if ($this->onAfterInstall($route) === false) + { + return false; + } + + if ($route == 'install') + { + $this->publishExtension(); + } + + if ($this->show_message) + { + $this->addInstalledMessage(); + } + + JFactory::getCache()->clean('com_plugins'); + JFactory::getCache()->clean('_system'); + + return true; + } + + public function isInstalled() + { + if ( ! is_file($this->getInstalledXMLFile())) + { + return false; + } + + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('extension_id')) + ->from('#__extensions') + ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); + $this->db->setQuery($query, 0, 1); + $result = $this->db->loadResult(); + + return empty($result) ? false : true; + } + + public function getMainFolder() + { + switch ($this->extension_type) + { + case 'plugin' : + return JPATH_PLUGINS . '/' . $this->plugin_folder . '/' . $this->extname; + + case 'component' : + return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; + + case 'module' : + return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; + + case 'library' : + return JPATH_SITE . '/libraries/' . $this->extname; + } + } + + public function getInstalledXMLFile() + { + return $this->getXMLFile($this->getMainFolder()); + } + + public function getCurrentXMLFile() + { + return $this->getXMLFile(__DIR__); + } + + public function getXMLFile($folder) + { + switch ($this->extension_type) + { + case 'module' : + return $folder . '/mod_' . $this->extname . '.xml'; + + default : + return $folder . '/' . $this->extname . '.xml'; + } + } + + public function uninstallExtension($extname, $type = 'plugin', $folder = 'system', $show_message = true) + { + if (empty($extname)) + { + return; + } + + $folders = []; + + switch ($type) + { + case 'plugin'; + $folders[] = JPATH_PLUGINS . '/' . $folder . '/' . $extname; + break; + + case 'component': + $folders[] = JPATH_ADMINISTRATOR . '/components/com_' . $extname; + $folders[] = JPATH_SITE . '/components/com_' . $extname; + break; + + case 'module': + $folders[] = JPATH_ADMINISTRATOR . '/modules/mod_' . $extname; + $folders[] = JPATH_SITE . '/modules/mod_' . $extname; + break; + } + + if ( ! $this->foldersExist($folders)) + { + return; + } + + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('extension_id')) + ->from('#__extensions') + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName($type, $extname))) + ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($type)); + + if ($type == 'plugin') + { + $query->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($folder)); + } + + $this->db->setQuery($query); + $ids = $this->db->loadColumn(); + + if (empty($ids)) + { + foreach ($folders as $folder) + { + JFolder::delete($folder); + } + + return; + } + + $ignore_ids = JFactory::getApplication()->getUserState('rl_ignore_uninstall_ids', []); + + if (JFactory::getApplication()->input->get('option') == 'com_installer' && JFactory::getApplication()->input->get('task') == 'remove') + { + // Don't attempt to uninstall extensions that are already selected to get uninstalled by them selves + $ignore_ids = array_merge($ignore_ids, JFactory::getApplication()->input->get('cid', [], 'array')); + JFactory::getApplication()->input->set('cid', array_merge($ignore_ids, $ids)); + } + + $ids = array_diff($ids, $ignore_ids); + + if (empty($ids)) + { + return; + } + + $ignore_ids = array_merge($ignore_ids, $ids); + JFactory::getApplication()->setUserState('rl_ignore_uninstall_ids', $ignore_ids); + + foreach ($ids as $id) + { + $tmpInstaller = new JInstaller; + $tmpInstaller->uninstall($type, $id); + } + + if ($show_message) + { + JFactory::getApplication()->enqueueMessage( + JText::sprintf( + 'COM_INSTALLER_UNINSTALL_SUCCESS', + JText::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($type)) + ) + ); + } + } + + public function foldersExist($folders = []) + { + foreach ($folders as $folder) + { + if (is_dir($folder)) + { + return true; + } + } + + return false; + } + + public function uninstallPlugin($extname, $folder = 'system', $show_message = true) + { + $this->uninstallExtension($extname, 'plugin', $folder, $show_message); + } + + public function uninstallComponent($extname, $show_message = true) + { + $this->uninstallExtension($extname, 'component', null, $show_message); + } + + public function uninstallModule($extname, $show_message = true) + { + $this->uninstallExtension($extname, 'module', null, $show_message); + } + + public function publishExtension() + { + switch ($this->extension_type) + { + case 'plugin' : + $this->publishPlugin(); + + case 'module' : + $this->publishModule(); + } + } + + public function publishPlugin() + { + $query = $this->db->getQuery(true) + ->update('#__extensions') + ->set($this->db->quoteName('enabled') . ' = 1') + ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) + ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); + $this->db->setQuery($query); + $this->db->execute(); + } + + public function publishModule() + { + // Get module id + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('id')) + ->from('#__modules') + ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) + ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + if ( ! $id) + { + return; + } + + // check if module is already in the modules_menu table (meaning is is already saved) + $query->clear() + ->select($this->db->quoteName('moduleid')) + ->from('#__modules_menu') + ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); + $this->db->setQuery($query, 0, 1); + $exists = $this->db->loadResult(); + + if ($exists) + { + return; + } + + // Get highest ordering number in position + $query->clear() + ->select($this->db->quoteName('ordering')) + ->from('#__modules') + ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) + ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) + ->order('ordering DESC'); + $this->db->setQuery($query, 0, 1); + $ordering = $this->db->loadResult(); + $ordering++; + + // publish module and set ordering number + $query->clear() + ->update('#__modules') + ->set($this->db->quoteName('published') . ' = 1') + ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) + ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) + ->where($this->db->quoteName('id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + + // add module to the modules_menu table + $query->clear() + ->insert('#__modules_menu') + ->columns([$this->db->quoteName('moduleid'), $this->db->quoteName('menuid')]) + ->values((int) $id . ', 0'); + $this->db->setQuery($query); + $this->db->execute(); + } + + public function addInstalledMessage() + { + JFactory::getApplication()->enqueueMessage( + JText::sprintf( + JText::_($this->install_type == 'update' ? 'RLI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'RLI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), + '' . JText::_($this->name) . '', + '' . $this->getVersion() . '', + $this->getFullType() + ) + ); + } + + public function getPrefix() + { + switch ($this->extension_type) + { + case 'plugin'; + return JText::_('plg_' . strtolower($this->plugin_folder)); + + case 'component': + return JText::_('com'); + + case 'module': + return JText::_('mod'); + + case 'library': + return JText::_('lib'); + + default: + return $this->extension_type; + } + } + + public function getElementName($type = null, $extname = null) + { + $type = is_null($type) ? $this->extension_type : $type; + $extname = is_null($extname) ? $this->extname : $extname; + + switch ($type) + { + case 'component' : + return 'com_' . $extname; + + case 'module' : + return 'mod_' . $extname; + + case 'plugin' : + default: + return $extname; + } + } + + public function getFullType() + { + return JText::_('RLI_' . strtoupper($this->getPrefix())); + } + + public function getVersion($file = '') + { + $file = $file ?: $this->getCurrentXMLFile(); + + if ( ! is_file($file)) + { + return ''; + } + + $xml = JApplicationHelper::parseXMLInstallFile($file); + + if ( ! $xml || ! isset($xml['version'])) + { + return ''; + } + + return $xml['version']; + } + + public function isNewer() + { + if ( ! $installed_version = $this->getVersion($this->getInstalledXMLFile())) + { + return true; + } + + $package_version = $this->getVersion(); + + return version_compare($installed_version, $package_version, '<='); + } + + public function canInstall() + { + // The extension is not installed yet + if ( ! $installed_version = $this->getVersion($this->getInstalledXMLFile())) + { + return true; + } + + // The free version is installed. So any version is ok to install + if (strpos($installed_version, 'PRO') === false) + { + return true; + } + + // Current package is a pro version, so all good + if (strpos($this->getVersion(), 'PRO') !== false) + { + return true; + } + + JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); + + JFactory::getApplication()->enqueueMessage(JText::_('RLI_ERROR_PRO_TO_FREE'), 'error'); + + JFactory::getApplication()->enqueueMessage( + html_entity_decode( + JText::sprintf( + 'RLI_ERROR_UNINSTALL_FIRST', + '', + '', + JText::_($this->name) + ) + ), 'error' + ); + + return false; + } + + /* + * Fixes incorrectly formed versions because of issues in old packager + */ + public function fixFileVersions($file) + { + if (is_array($file)) + { + foreach ($file as $f) + { + self::fixFileVersions($f); + } + + return; + } + + if ( ! is_string($file) || ! is_file($file)) + { + return; + } + + $contents = file_get_contents($file); + + if ( + strpos($contents, 'FREEFREE') === false + && strpos($contents, 'FREEPRO') === false + && strpos($contents, 'PROFREE') === false + && strpos($contents, 'PROPRO') === false + ) + { + return; + } + + $contents = str_replace( + ['FREEFREE', 'FREEPRO', 'PROFREE', 'PROPRO'], + ['FREE', 'PRO', 'FREE', 'PRO'], + $contents + ); + + JFile::write($file, $contents); + } + + public function onBeforeInstall($route) + { + if ( ! $this->canInstall()) + { + return false; + } + + return true; + } + + public function onAfterInstall($route) + { + } + + public function delete($files = []) + { + foreach ($files as $file) + { + if (is_dir($file)) + { + JFolder::delete($file); + } + + if (is_file($file)) + { + JFile::delete($file); + } + } + } + + public function fixAssetsRules($rules = '{"core.admin":[],"core.manage":[]}') + { + // replace default rules value {} with the correct initial value + $query = $this->db->getQuery(true) + ->update($this->db->quoteName('#__assets')) + ->set($this->db->quoteName('rules') . ' = ' . $this->db->quote($rules)) + ->where($this->db->quoteName('title') . ' = ' . $this->db->quote('com_' . $this->extname)) + ->where($this->db->quoteName('rules') . ' = ' . $this->db->quote('{}')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function fixExtensionNames() + { + switch ($this->extension_type) + { + case 'module' : + $this->fixModuleNames(); + } + } + + private function fixModuleNames() + { + // Get module id + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('id')) + ->from('#__modules') + ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) + ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); + $this->db->setQuery($query, 0, 1); + $module_id = $this->db->loadResult(); + + if (empty($module_id)) + { + return; + } + + $title = 'Regular Labs - ' . JText::_($this->name); + + $query->clear() + ->update('#__modules') + ->set($this->db->quoteName('title') . ' = ' . $this->db->quote($title)) + ->where($this->db->quoteName('id') . ' = ' . (int) $module_id) + ->where($this->db->quoteName('title') . ' LIKE ' . $this->db->quote('NoNumber%')); + $this->db->setQuery($query); + $this->db->execute(); + + // Fix module assets + + // Get asset id + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('id')) + ->from('#__assets') + ->where($this->db->quoteName('name') . ' = ' . $this->db->quote('com_modules.module.' . (int) $module_id)) + ->where($this->db->quoteName('title') . ' LIKE ' . $this->db->quote('NoNumber%')); + $this->db->setQuery($query, 0, 1); + $asset_id = $this->db->loadResult(); + + if (empty($asset_id)) + { + return; + } + + $query->clear() + ->update('#__assets') + ->set($this->db->quoteName('title') . ' = ' . $this->db->quote($title)) + ->where($this->db->quoteName('id') . ' = ' . (int) $asset_id); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function updateUpdateSites() + { + $this->removeOldUpdateSites(); + $this->updateNamesInUpdateSites(); + $this->updateHttptoHttpsInUpdateSites(); + $this->removeDuplicateUpdateSite(); + $this->updateDownloadKey(); + } + + private function removeOldUpdateSites() + { + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('nonumber.nl%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + if ( ! $id) + { + return; + } + + $query->clear() + ->delete('#__update_sites') + ->where($this->db->quoteName('update_site_id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + + $query->clear() + ->delete('#__update_sites_extensions') + ->where($this->db->quoteName('update_site_id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function updateNamesInUpdateSites() + { + $name = JText::_($this->name); + if ($this->alias != 'extensionmanager') + { + $name = 'Regular Labs - ' . $name; + } + + $query = $this->db->getQuery(true) + ->update('#__update_sites') + ->set($this->db->quoteName('name') . ' = ' . $this->db->quote($name)) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function updateHttptoHttpsInUpdateSites() + { + $query = $this->db->getQuery(true) + ->update('#__update_sites') + ->set($this->db->quoteName('location') . ' = REPLACE(' + . $this->db->quoteName('location') . ', ' + . $this->db->quote('http://') . ', ' + . $this->db->quote('https://') + . ')') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('http://download.regularlabs.com%')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function removeDuplicateUpdateSite() + { + // First check to see if there is a pro entry + + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')) + ->where($this->db->quoteName('location') . ' NOT LIKE ' . $this->db->quote('%pro=1%')); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + // Otherwise just get the first match + if ( ! $id) + { + $query->clear() + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + // Remove pro=1 from the found update site + $query->clear() + ->update('#__update_sites') + ->set($this->db->quoteName('location') + . ' = replace(' . $this->db->quoteName('location') . ', ' . $this->db->quote('&pro=1') . ', ' . $this->db->quote('') . ')') + ->where($this->db->quoteName('update_site_id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + } + + if ( ! $id) + { + return; + } + + $query->clear() + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')) + ->where($this->db->quoteName('update_site_id') . ' != ' . $id); + $this->db->setQuery($query); + $ids = $this->db->loadColumn(); + + if (empty($ids)) + { + return; + } + + $query->clear() + ->delete('#__update_sites') + ->where($this->db->quoteName('update_site_id') . ' IN (' . implode(',', $ids) . ')'); + $this->db->setQuery($query); + $this->db->execute(); + + $query->clear() + ->delete('#__update_sites_extensions') + ->where($this->db->quoteName('update_site_id') . ' IN (' . implode(',', $ids) . ')'); + $this->db->setQuery($query); + $this->db->execute(); + } + + // Save the download key from the Regular Labs Extension Manager config to the update sites + private function updateDownloadKey() + { + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('params')) + ->from('#__extensions') + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote('com_regularlabsmanager')); + $this->db->setQuery($query); + $params = $this->db->loadResult(); + + if ( ! $params) + { + return; + } + + $params = json_decode($params); + + if ( ! isset($params->key)) + { + return; + } + + // Add the key on all regularlabs.com urls + $query->clear() + ->update('#__update_sites') + ->set($this->db->quoteName('extra_query') . ' = ' . $this->db->quote('k=' . $params->key)) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function removeAdminCache() + { + $this->delete([JPATH_ADMINISTRATOR . '/cache/regularlabs']); + $this->delete([JPATH_ADMINISTRATOR . '/cache/nonumber']); + } + + private function removeGlobalLanguageFiles() + { + if ($this->extension_type == 'library') + { + return; + } + + $language_files = JFolder::files(JPATH_ADMINISTRATOR . '/language', '\.' . $this->getPrefix() . '_' . $this->extname . '\.', true, true); + + // Remove override files + foreach ($language_files as $i => $language_file) + { + if (strpos($language_file, '/overrides/') === false) + { + continue; + } + + unset($language_files[$i]); + } + + if (empty($language_files)) + { + return; + } + + JFile::delete($language_files); + } + + private function removeUnusedLanguageFiles() + { + if ($this->extension_type == 'library') + { + return; + } + + $installed_languages = array_merge( + JFolder::folders(JPATH_SITE . '/language'), + JFolder::folders(JPATH_ADMINISTRATOR . '/language') + ); + + $languages = array_diff( + JFolder::folders(__DIR__ . '/language'), + $installed_languages + ); + + $delete_languages = []; + + foreach ($languages as $language) + { + $delete_languages[] = $this->getMainFolder() . '/language/' . $language; + } + + if (empty($delete_languages)) + { + return; + } + + // Remove folders + $this->delete($delete_languages); + } +} diff --git a/deployed/regularlabs/plugins/system/modals/script.install.php b/deployed/regularlabs/plugins/system/modals/script.install.php new file mode 100644 index 00000000..34d35b40 --- /dev/null +++ b/deployed/regularlabs/plugins/system/modals/script.install.php @@ -0,0 +1,76 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +require_once __DIR__ . '/script.install.helper.php'; + +class PlgSystemModalsInstallerScript extends PlgSystemModalsInstallerScriptHelper +{ + public $name = 'MODALS'; + public $alias = 'modals'; + public $extension_type = 'plugin'; + + public function uninstall($adapter) + { + $this->uninstallPlugin($this->extname, 'editors-xtd'); + } + + public function onAfterInstall($route) + { + // Copy modal.php to system template folder + JFile::copy(__DIR__ . '/modal.php', JPATH_SITE . '/templates/system/modal.php'); + + $this->fixOldParams(); + } + + public function fixOldParams() + { + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('params')) + ->from('#__extensions') + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote('modals')) + ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote('system')); + $this->db->setQuery($query); + $params = $this->db->loadResult(); + + if (empty($params)) + { + return; + } + + $params = json_decode($params); + + if (empty($params)) + { + return; + } + + // Fix params changed since v9.9.0 + + if ( ! isset($params->images_use_title_attribute) || $params->images_use_title_attribute !== 1) + { + return; + } + + $params->images_use_title_attribute = 'title'; + + $query->clear() + ->update('#__extensions') + ->set($this->db->quoteName('params') . ' = ' . $this->db->quote(json_encode($params))) + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote('modals')) + ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote('system')); + $this->db->setQuery($query); + $this->db->execute(); + + JFactory::getCache()->clean('_system'); + } +} diff --git a/deployed/regularlabs/plugins/system/modals/src/Clean.php b/deployed/regularlabs/plugins/system/modals/src/Clean.php new file mode 100644 index 00000000..a6dea418 --- /dev/null +++ b/deployed/regularlabs/plugins/system/modals/src/Clean.php @@ -0,0 +1,37 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Plugin\System\Modals; + +defined('_JEXEC') or die; + +use RegularLabs\Library\Protect as RL_Protect; + +class Clean +{ + /** + * Just in case you can't figure the method name out: this cleans the left-over junk + */ + public static function cleanLeftoverJunk(&$string) + { + list($tag_start, $tag_end) = Params::getTagCharacters(); + + Protect::unprotectTags($string); + + RL_Protect::removeFromHtmlTagContent($string, Params::getTags(true)); + RL_Protect::removeInlineComments($string, 'Modals'); + RL_Protect::removePluginTags($string, + Params::getTagWords(), + $tag_start, + $tag_end + ); + } +} diff --git a/deployed/regularlabs/plugins/system/modals/src/Data.php b/deployed/regularlabs/plugins/system/modals/src/Data.php new file mode 100644 index 00000000..ff68c724 --- /dev/null +++ b/deployed/regularlabs/plugins/system/modals/src/Data.php @@ -0,0 +1,168 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Plugin\System\Modals; + +defined('_JEXEC') or die; + +use JFactory; +use RegularLabs\Library\RegEx as RL_RegEx; +use RegularLabs\Library\Uri as RL_Uri; + +class Data +{ + + public static function setDataWidthHeight(&$data, $isexternal) + { + self::setDataAxis($data, $isexternal, 'width'); + self::setDataAxis($data, $isexternal, 'height'); + } + + public static function setDataAxis(&$data, $isexternal, $axis = 'width') + { + if ( ! empty($data[$axis])) + { + return; + } + + $params = Params::get(); + + if ($isexternal) + { + $data[$axis] = $params->{'external' . $axis} ?: $params->{$axis} ?: '95%'; + + return; + } + + $data[$axis] = $params->{$axis} ?: $params->{'external' . $axis} ?: '95%'; + } + + + public static function flattenAttributeList($attributes) + { + $params = Params::get(); + + $string = ''; + foreach ($attributes as $key => $val) + { + $key = trim($key); + + // Ignore attributes when key is empty + if ($key == '') + { + continue; + } + + $val = trim($val); + + // Ignore attributes when value is empty, but not a title or alt attribute + if ($val == '' && ! in_array($key, ['alt', 'title'])) + { + continue; + } + + if (is_bool($val) && in_array($key, $params->booleans)) + { + $val = $val ? 'true' : 'false'; + } + + $string .= ' ' . $key . '="' . $val . '"'; + } + + return $string; + } + + public static function flattenDataAttributeList(&$dat) + { + if (isset($dat['width'])) + { + unset($dat['externalWidth']); + } + + if (isset($dat['height'])) + { + unset($dat['externalHeight']); + } + + $data = []; + foreach ($dat as $key => $val) + { + if ( ! $str = self::flattenDataAttribute($key, $val)) + { + continue; + } + $data[] = $str; + } + + return empty($data) ? '' : ' ' . implode(' ', $data); + } + + public static function flattenDataAttribute($key, $val) + { + if ($key == '') + { + return false; + } + + if (strpos($key, 'title_') !== false || strpos($key, 'description_') !== false) + { + return false; + } + + $key = $key == 'externalWidth' ? 'width' : $key; + $key = $key == 'externalHeight' ? 'height' : $key; + + if ( ! in_array($key, ['title', 'iframe', 'video', 'class', 'rel', 'classname']) + && strpos($key, 'width') === false + && strpos($key, 'height') === false + ) + { + return false; + } + + $val = str_replace('"', '"', $val); + + if ($key == 'rel') + { + // map group value to rel + return 'rel="' . $val . '"'; + } + + + if (($key == 'width' || $key == 'height') && strpos($val, '%') === false) + { + // set param to innerWidth/innerHeight if value of width/height is a percentage + return 'data-modal-inner-' . $key . '="' . $val . '"'; + } + + $params = Params::get(); + + if (in_array(strtolower($key), $params->booleans)) + { + $val = $val ? 'true' : 'false'; + } + + if ($val == '') + { + return false; + } + + if (in_array(strtolower($key), $params->paramNamesLowercase)) + { + // fix use of lowercase params that should contain uppercase letters + $key = $params->paramNamesCamelcase[array_search(strtolower($key), $params->paramNamesLowercase)]; + $key = strtolower(RL_RegEx::replace('([A-Z])', '-\1', $key, '')); + } + + return 'data-modal-' . $key . '="' . $val . '"'; + } + +} diff --git a/deployed/regularlabs/plugins/system/modals/src/Document.php b/deployed/regularlabs/plugins/system/modals/src/Document.php new file mode 100644 index 00000000..5cb56384 --- /dev/null +++ b/deployed/regularlabs/plugins/system/modals/src/Document.php @@ -0,0 +1,215 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Plugin\System\Modals; + +defined('_JEXEC') or die; + +use JFactory; +use JHtml; +use JRoute; +use JText; +use RegularLabs\Library\Document as RL_Document; + +class Document +{ + public static function addHeadStuff() + { + // do not load scripts/styles on feeds or print pages + if (RL_Document::isFeed() || JFactory::getApplication()->input->getInt('print', 0)) + { + return; + } + + $params = Params::get(); + + if (JFactory::getApplication()->input->getInt('ml', 0) && $params->add_redirect) + { + self::addRedirectScript(); + + return; + } + + if ($params->load_jquery) + { + JHtml::_('jquery.framework'); + } + + $defaults = self::getDefaults(); + $defaults['current'] = JText::sprintf('MDL_MODALTXT_CURRENT', '{current}', '{total}'); + $defaults['previous'] = JText::_('MDL_MODALTXT_PREVIOUS'); + $defaults['next'] = JText::_('MDL_MODALTXT_NEXT'); + $defaults['close'] = JText::_('MDL_MODALTXT_CLOSE'); + $defaults['xhrError'] = JText::_('MDL_MODALTXT_XHRERROR'); + $defaults['imgError'] = JText::_('MDL_MODALTXT_IMGERROR'); + + $options = [ + 'class' => $params->class ?: 'modals', + 'defaults' => $defaults, + 'auto_correct_size' => (int) $params->auto_correct_size, + 'auto_correct_size_delay' => (int) $params->auto_correct_size_delay, + ]; + + RL_Document::scriptOptions($options, 'Modals'); + + JHtml::script('modals/jquery.touchSwipe.min.js', false, true); + JHtml::script('modals/jquery.colorbox-min.js', false, true); + RL_Document::script('modals/script.min.js', ($params->media_versioning ? '9.13.0' : '')); + + if ($params->load_stylesheet) + { + RL_Document::style('modals/' . $params->style . '.min.css'); + } + } + + public static function removeHeadStuff(&$html) + { + $params = Params::get(); + + // Don't remove if modals class is found + if (strpos($html, $params->class) !== false) + { + return; + } + + // remove style and script if no items are found + RL_Document::removeScriptsStyles($html, 'Modals'); + RL_Document::removeScriptsOptions($html, 'Modals'); + } + + public static function addPrint($url) + { + $url = explode('#', $url, 2); + + $url[0] .= (strpos($url[0], '?') === false) ? '?print=1' : '&print=1'; + + $url = implode('#', $url); + + return $url; + } + + public static function addUrlAttributes($url, $iframe = false, $fullpage = false, $print = false) + { + $url = explode('#', $url, 2); + + if (substr($url[0], 0, 4) != 'http' + && strpos($url[0], 'index.php') === 0 + && strpos($url[0], '/') === false + ) + { + $url[0] = JRoute::_($url[0]); + } + + $url[0] = self::setUrlAttribute($url[0], 'ml'); + + if ($iframe) + { + $url[0] = self::setUrlAttribute($url[0], 'iframe'); + } + + if ($fullpage) + { + $url[0] = self::setUrlAttribute($url[0], 'fullpage'); + } + + if ($print) + { + $url[0] = self::setUrlAttribute($url[0], 'print'); + } + + $url = implode('#', $url); + + return $url; + } + + public static function setUrlAttribute($url, $key) + { + if (strpos($url, $key . '=1') !== false) + { + return $url; + } + + return $url + . (strpos($url, '?') === false ? '?' : '&') + . $key . '=1'; + } + + public static function setTemplate() + { + $params = Params::get(); + + JFactory::getApplication()->input->set('tmpl', JFactory::getApplication()->input->getWord('tmpl', $params->tmpl)); + } + + private static function addRedirectScript() + { + // Add redirect script + $script = + ";if( parent.location.href === window.location.href ) { + loc = window.location.href.replace(/(\?|&)ml=1(&iframe=1(&fullpage=1)?)?(&|$)/, '$1'); + loc = loc.replace(/(\?|&)$/, ''); + if(parent.location.href !== loc) { + parent.location.href = loc; + } + }"; + + if (JFactory::getApplication()->input->get('iframe')) + { + RL_Document::scriptDeclaration($script); + + return; + } + + if ( ! $buffer = RL_Document::getBuffer()) + { + return; + } + + $buffer = + '' + . $buffer; + + RL_Document::setBuffer($buffer); + } + + private static function getDefaults() + { + $params = Params::get(); + + $keyvals = [ + 'opacity' => 0.9, + 'width' => '', + 'height' => '', + 'initialWidth' => 600, + 'initialHeight' => 450, + 'maxWidth' => false, + 'maxHeight' => false, + ]; + + $defaults = []; + + foreach ($keyvals as $key => $default) + { + $param_key = strtolower($key); + + if ( ! isset($params->{$param_key}) || $params->{$param_key} == $default) + { + continue; + } + + $val = $params->{$param_key}; + + $defaults[$key] = $val; + } + + return $defaults; + } +} diff --git a/deployed/regularlabs/plugins/system/modals/src/File.php b/deployed/regularlabs/plugins/system/modals/src/File.php new file mode 100644 index 00000000..332580b8 --- /dev/null +++ b/deployed/regularlabs/plugins/system/modals/src/File.php @@ -0,0 +1,219 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Plugin\System\Modals; + +defined('_JEXEC') or die; + +use RegularLabs\Library\ArrayHelper as RL_Array; +use RegularLabs\Library\RegEx as RL_RegEx; +use RegularLabs\Library\StringHelper as RL_String; + +class File +{ + public static function isExternal($url) + { + if (strpos($url, '://') === false) + { + return false; + } + + // hostname: give preference to SERVER_NAME, because this includes subdomains + $hostname = ($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST']; + + return ! (strpos(RL_RegEx::replace('^.*?://', '', $url), $hostname) === 0); + } + + public static function isMedia($url, $filetypes = [], $ignore = false) + { + $filetype = self::getFiletype($url); + + if ( ! $filetype) + { + return false; + } + + if (empty($filetypes)) + { + $params = Params::get(); + + $filetypes = $params->mediafiles; + $ignore = false; + } + + if ( ! $filetypes) + { + return false; + } + + if (strpos($filetypes[0], ',') !== false) + { + $filetypes = RL_Array::toArray($filetypes[0]); + } + + $pass = in_array($filetype, $filetypes); + + return $ignore ? ! $pass : $pass; + } + + public static function isVideo($url, $data) + { + if (isset($data['video']) && $data['video'] == 'true') + { + return true; + } + + // Return true for external video urls + if (strpos($url, 'youtu.be') !== false + || strpos($url, 'youtube.com') !== false + || strpos($url, 'vimeo.com') !== false + ) + { + return true; + } + + $filetype = self::getFiletype($url); + + $filetypes = [ + '3g2', + '3gp', + 'avi', + 'divx', + 'f4v', + 'flv', + 'm4v', + 'mov', + 'mp4', + 'mpe', + 'mpeg', + 'mpg', + 'ogv', + 'swf', + 'webm', + 'wmv', + ]; + + return in_array($filetype, $filetypes); + } + + public static function isIframe($url, &$data) + { + if ( ! empty($data['inline'])) + { + return false; + } + + $params = Params::get(); + + if (self::isMedia($url, $params->iframefiles)) + { + return true; + } + + if (self::isMedia($url)) + { + unset($data['iframe']); + + return false; + } + + if (empty($data['iframe'])) + { + return $params->iframe; + } + + return ($data['iframe'] !== 0 && $data['iframe'] !== 'false'); + } + + public static function retinaImageExists($url) + { + $params = Params::get(); + + $retina_file = RL_RegEx::replace('\.([a-z0-9]+)$', $params->retinasuffix, $url); + + return is_file(JPATH_SITE . '/' . $retina_file); + } + + public static function getFiletype($url) + { + $info = pathinfo($url); + if ( ! isset($info['extension'])) + { + return ''; + } + + $ext = explode('?', $info['extension']); + + return strtolower($ext[0]); + } + + public static function getFileName($url) + { + return basename($url); + } + + public static function getFileTitle($url) + { + $info = pathinfo($url); + + return isset($info['filename']) ? $info['filename'] : ''; + } + + public static function getFilePath($url) + { + return dirname($url) . '/'; + } + + public static function getTitle($url, $case) + { + $file_name = basename($url); + + $title = explode('.', $file_name); + $title = $title[0]; + $title = RL_RegEx::replace('[_-]([0-9]+|[a-z])$', '', $title); + $title = str_replace(['-', '_'], ' ', $title); + + $params = Params::get(); + + switch ($case) + { + case 'lowercase': + $title = RL_String::strtolower($title); + break; + case 'uppercase': + $title = RL_String::strtoupper($title); + break; + case 'uppercasefirst': + $title = RL_String::strtoupper(RL_String::substr($title, 0, 1)) + . RL_String::strtolower(RL_String::substr($title, 1)); + break; + case 'titlecase': + $title = function_exists('mb_convert_case') + ? mb_convert_case(RL_String::strtolower($title), MB_CASE_TITLE) + : ucwords(strtolower($title)); + break; + case 'titlecase_smart': + $title = function_exists('mb_convert_case') + ? mb_convert_case(RL_String::strtolower($title), MB_CASE_TITLE) + : ucwords(strtolower($title)); + $lowercase_words = explode(',', ' ' . str_replace(',', ' , ', RL_String::strtolower($params->lowercase_words)) . ' '); + $title = str_ireplace($lowercase_words, $lowercase_words, $title); + break; + } + + return $title; + } + + public static function trimFolder($folder) + { + return trim(str_replace(['\\', '//'], '/', $folder), '/'); + } +} diff --git a/deployed/regularlabs/plugins/system/modals/src/Gallery.php b/deployed/regularlabs/plugins/system/modals/src/Gallery.php new file mode 100644 index 00000000..d945c6ad --- /dev/null +++ b/deployed/regularlabs/plugins/system/modals/src/Gallery.php @@ -0,0 +1,15 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Plugin\System\Modals; + +defined('_JEXEC') or die; + diff --git a/deployed/regularlabs/plugins/system/modals/src/Helper.php b/deployed/regularlabs/plugins/system/modals/src/Helper.php new file mode 100644 index 00000000..00510b76 --- /dev/null +++ b/deployed/regularlabs/plugins/system/modals/src/Helper.php @@ -0,0 +1,83 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Plugin\System\Modals; + +defined('_JEXEC') or die; + +use JFactory; +use RegularLabs\Library\Article as RL_Article; +use RegularLabs\Library\Document as RL_Document; +use RegularLabs\Library\Html as RL_Html; + +/** + * Plugin that replaces stuff + */ +class Helper +{ + public function onContentPrepare($context, &$article, &$params) + { + $area = isset($article->created_by) ? 'article' : 'other'; + $context = (($params instanceof \JRegistry) && $params->get('rl_search')) ? 'com_search.' . $params->get('readmore_limit') : $context; + + RL_Article::process($article, $context, $this, 'replaceTags', [$area, $context]); + } + + public function onAfterDispatch() + { + Document::addHeadStuff(); + + if ( ! $buffer = RL_Document::getBuffer()) + { + return; + } + + if (JFactory::getApplication()->input->getInt('ml', 0) && ! JFactory::getApplication()->input->getInt('fullpage', 0)) + { + Document::setTemplate(); + } + + if ( ! Replace::replaceTags($buffer, 'component')) + { + return; + } + + RL_Document::setBuffer($buffer); + } + + public function onAfterRender() + { + $html = JFactory::getApplication()->getBody(); + + if ($html == '') + { + return; + } + + // only do stuff in body + list($pre, $body, $post) = RL_Html::getBody($html); + Replace::replaceTags($body, 'body'); + + Clean::cleanLeftoverJunk($pre); + Clean::cleanLeftoverJunk($post); + + $html = $pre . $body . $post; + + Document::removeHeadStuff($html); + + JFactory::getApplication()->setBody($html); + } + + public function replaceTags(&$string, $area = 'article', $context = '') + { + Replace::replaceTags($string, $area, $context); + } +} diff --git a/deployed/regularlabs/plugins/system/modals/src/Image.php b/deployed/regularlabs/plugins/system/modals/src/Image.php new file mode 100644 index 00000000..d945c6ad --- /dev/null +++ b/deployed/regularlabs/plugins/system/modals/src/Image.php @@ -0,0 +1,15 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Plugin\System\Modals; + +defined('_JEXEC') or die; + diff --git a/deployed/regularlabs/plugins/system/modals/src/Link.php b/deployed/regularlabs/plugins/system/modals/src/Link.php new file mode 100644 index 00000000..77fb8df7 --- /dev/null +++ b/deployed/regularlabs/plugins/system/modals/src/Link.php @@ -0,0 +1,378 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Plugin\System\Modals; + +defined('_JEXEC') or die; + +use ContentHelperRoute; +use JFactory; +use JText; +use RegularLabs\Library\PluginTag as RL_PluginTag; +use RegularLabs\Library\RegEx as RL_RegEx; +use RegularLabs\Library\StringHelper as RL_String; + +class Link +{ + public static function build($attributes, $data, $content = '') + { + + self::setVideoUrl($attributes, $data); + + $isexternal = File::isExternal($attributes->href); + $ismedia = File::isMedia($attributes->href); + $isvideo = File::isVideo($attributes->href, $data); + $fullpage = (empty($data['fullpage']) || $isexternal) ? false : (bool) $data['fullpage']; + $isiframe = $fullpage || File::isIframe($attributes->href, $data); + + $params = Params::get(); + + if (isset($attributes->{'data-modal-title'}) && ! isset($data['title'])) + { + $data['title'] = $attributes->{'data-modal-title'}; + } + + if (isset($attributes->title) && ! isset($data['title'])) + { + $data['title'] = $attributes->title; + } + + if ($ismedia) + { + $data['classname'] = (isset($data['classname']) ? $data['classname'] . ' ' : '') . 'is_image'; + $data['image'] = 'true'; + + if ( ! isset($data['title'])) + { + $auto_titles = isset($data['auto_titles']) ? $data['auto_titles'] : $params->auto_titles; + $title_case = isset($data['title_case']) ? $data['title_case'] : $params->title_case; + if ($auto_titles) + { + $data['title'] = File::getTitle($attributes->href, $title_case); + } + } + + } + unset($data['auto_titles']); + + // Force/overrule certain data values + if ($isiframe || ($isexternal && ! $ismedia)) + { + // use iframe mode for external urls + $data['iframe'] = 'true'; + Data::setDataWidthHeight($data, $isexternal); + } + + if ($isvideo) + { + $data['classname'] = (isset($data['classname']) ? $data['classname'] . ' ' : '') . 'is_video'; + $data['video'] = 'true'; + } + + if ($attributes->href && $attributes->href[0] != '#' && ! $isexternal && ! $ismedia) + { + $attributes->href = Document::addUrlAttributes($attributes->href, $isiframe, $fullpage, ! empty($data['print'])); + } + + + if (empty($data['title'])) + { + $data['classname'] = (isset($data['classname']) ? $data['classname'] . ' ' : '') . 'no_title'; + $data['title'] = ''; + } + + + // Add aria label for empty links for accessibility + if (empty($content)) + { + $label = isset($attributes->title) + ? $attributes->title + : (isset($data['title']) + ? self::cleanTitle($data['title']) + : '' + ); + + $attributes->{'aria-label'} = $label ?: 'Popup link'; + } + + return + '' + . $content; + } + + private static function cleanTitle($string) + { + $string = str_replace('
', ' - ', $string); + + return RL_String::removeHtml($string); + } + + public static function get($string, $link = '', $content = '') + { + list($attributes, $data, $extra) = self::getData($string, $link); + + return [self::build($attributes, $data, $content), $extra]; + } + + public static function getData($string, $link = '') + { + $params = Params::get(); + + $attributes = self::prepareAttributeList($link); + + RL_PluginTag::protectSpecialChars($string); + + $is_old_syntax = + (strpos($string, '|') !== false) + || (strpos($string, '"') === false && strpos($string, '"') === false); + + if ($is_old_syntax) + { + // Replace open attribute with open=1 + $string = RL_RegEx::replace('(^|\|)open($|\|)', '\1open=1\2', $string); + + // Add empty url attribute to beginning if no url/href attribute is there, + // to prevent issues with grabbing values from old syntax + if (RL_RegEx::match('^([a-z]+)=', $string, $match)) + { + if ($match[1] != 'url' && $match[1] != 'href') + { + $string = 'url=|' . $string; + } + } + } + + RL_PluginTag::unprotectSpecialChars($string); + + // Get the values from the tag + $tag = RL_PluginTag::getAttributesFromString($string, 'url', $params->booleans); + + $key_aliases = [ + 'url' => ['href', 'link', 'image', 'src'], + 'gallery' => ['galery', 'images'], + ]; + + RL_PluginTag::replaceKeyAliases($tag, $key_aliases); + + if ( ! empty($tag->url)) + { + $attributes->href = self::cleanUrl($tag->url); + } + unset($tag->url); + + if ( ! empty($tag->target)) + { + $attributes->target = $tag->target; + } + unset($tag->target); + + $extra = ''; + + + $attributes->id = ! empty($tag->id) ? $tag->id : ''; + unset($tag->id); + + $attributes->class .= ! empty($tag->class) ? ' ' . $tag->class : ''; + unset($tag->class); + + if ( ! empty($tag->title)) + { + $tag->title = self::translateString($tag->title); + } + + if ( ! empty($tag->description)) + { + $tag->description = self::translateString($tag->description); + } + + // move onSomething params to attributes, except the modal callbacks + $callbacks = ['onopen', 'onload', 'oncomplete', 'oncleanup', 'onclosed']; + foreach ($tag as $key => $val) + { + if ( + substr($key, 0, 2) == 'on' + && ! in_array(strtolower($key), $callbacks) + && is_string($val) + ) + { + $attributes->{$key} = $val; + unset($tag->{$key}); + } + } + + $data = []; + + + // set data by values set in tag + foreach ($tag as $key => $val) + { + $data[strtolower($key)] = $val; + } + + return [$attributes, $data, $extra]; + } + + private static function translateString($string = '') + { + if (empty($string) || ! RL_RegEx::match('^[A-Z][A-Z0-9_]+$', $string)) + { + return $string; + } + + return JText::_($string); + } + + private static function prepareAttributeList($link) + { + $params = Params::get(); + + $attributes = (object) []; + $attributes->href = ''; + $attributes->class = $params->class; + $attributes->id = ''; + + if ( ! $link) + { + return $attributes; + } + + $link_attributes = self::getAttributeList(trim($link)); + + foreach ($link_attributes as $key => $val) + { + $key = trim($key); + $val = trim($val); + + if ($key == '' || $val == '') + { + continue; + } + + if ($key == 'class') + { + $attributes->{$key} = trim($attributes->{$key} . ' ' . $val); + continue; + } + + $attributes->{$key} = $val; + } + + return $attributes; + } + + public static function getAttributeList($string) + { + $attributes = (object) []; + + if ( ! $string) + { + return $attributes; + } + + $params = Params::get(); + + RL_RegEx::matchAll('([a-z0-9_-]+)\s*=\s*(?:"(.*?)"|\'(.*?)\')', $string, $params); + + if (empty($params)) + { + return $attributes; + } + + foreach ($params as $param) + { + $attributes->{$param[1]} = isset($param[3]) ? $param[3] : $param[2]; + } + + return $attributes; + } + + private static function cleanUrl($url) + { + return RL_RegEx::replace(']*>(.*?)', '\1', $url); + } + + private static function setVideoUrl(&$attributes, &$data) + { + + $attributes->href = self::fixVideoUrl($attributes->href, $data); + } + + private static function fixVideoUrl($url, &$data) + { + switch (true) + { + case( + strpos($url, 'youtu.be') !== false + || strpos($url, 'youtube.com') !== false + ) : + $data['video'] = 'true'; + + return self::fixUrlYoutube($url); + + case( + strpos($url, 'vimeo.com') !== false + ) : + $data['video'] = 'true'; + + return self::fixUrlVimeo($url); + } + + return $url; + } + + private static function fixUrlYoutube($url) + { + $regex = '(?:^youtube=|youtu\.be/?|youtube\.com/embed/?|youtube\.com\/watch\?v=)(?[^/&\?]+)(?:\?|&|&)?(?.*)$'; + + if ( ! RL_RegEx::match($regex, trim($url), $match)) + { + return $url; + } + + $url = 'https://www.youtube.com/embed/' . $match['id']; + + if ( ! empty($match['query'])) + { + $url .= '?' . $match['query']; + } + + if (strpos($match['query'], 'wmode=transparent') !== false) + { + return $url; + } + + $url .= (strpos($url, '?') === false ? '?' : '&') . 'wmode=transparent'; + + return $url; + } + + private static function fixUrlVimeo($url) + { + $regex = '(?:^vimeo=|vimeo\.com/(?:video/)?)(?[0-9]+)(?.*)$'; + + if ( ! RL_RegEx::match($regex, trim($url), $match)) + { + return $url; + } + + $url = 'https://player.vimeo.com/video/' . $match['id']; + + if ( ! empty($match['query'])) + { + $url .= '?' . $match['query']; + } + + return $url; + } +} diff --git a/deployed/regularlabs/plugins/system/modals/src/Params.php b/deployed/regularlabs/plugins/system/modals/src/Params.php new file mode 100644 index 00000000..a428ef05 --- /dev/null +++ b/deployed/regularlabs/plugins/system/modals/src/Params.php @@ -0,0 +1,180 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Plugin\System\Modals; + +defined('_JEXEC') or die; + +use RegularLabs\Library\ArrayHelper as RL_Array; +use RegularLabs\Library\Parameters as RL_Parameters; +use RegularLabs\Library\PluginTag as RL_PluginTag; +use RegularLabs\Library\RegEx as RL_RegEx; + +class Params +{ + protected static $params = null; + protected static $regexes = null; + + public static function get() + { + if ( ! is_null(self::$params)) + { + return self::$params; + } + + $params = RL_Parameters::getInstance()->getPluginParams('modals'); + + $params->tag = RL_PluginTag::clean($params->tag); + + $params->class = 'modal_link'; + // array_filter will remove any empty values + $params->classnames = $params->autoconvert_classnames ? RL_Array::toArray(str_replace(' ', ',', trim($params->classnames))) : []; + + $params->mediafiles = RL_Array::toArray(strtolower($params->mediafiles)); + $params->iframefiles = RL_Array::toArray(strtolower($params->iframefiles)); + + $params->paramNamesCamelcase = [ + 'innerWidth', 'innerHeight', 'initialWidth', 'initialHeight', + 'maxWidth', 'maxHeight', 'minWidth', 'minHeight', 'className', + ]; + $params->paramNamesLowercase = array_map('strtolower', $params->paramNamesCamelcase); + $params->paramNamesBooleans = [ + 'scalephotos', 'scrolling', 'inline', 'iframe', 'fastiframe', + 'photo', 'preloading', 'retinaimage', 'open', 'returnfocus', 'trapfocus', 'reposition', + 'loop', 'slideshow', 'slideshowauto', 'overlayclose', 'closebutton', 'esckey', 'arrowkey', 'fixed', + ]; + + $params->booleans = [ + 'openOnce', 'inline', 'iframe', 'fullpage', + 'auto_titles', + ]; + + self::$params = $params; + + return self::$params; + } + + public static function getTags($only_start_tags = false) + { + $params = self::get(); + + list($tag_start, $tag_end) = self::getTagCharacters(); + + $tags = [ + [ + $tag_start . $params->tag, + ], + [ + $tag_start . '/' . $params->tag . $tag_end, + ], + ]; + + return $only_start_tags ? $tags[0] : $tags; + } + + public static function getTagWords() + { + $params = self::get(); + + return [ + $params->tag, + ]; + } + + public static function getRegex($type = 'tag') + { + $regexes = self::getRegexes(); + + return isset($regexes->{$type}) ? $regexes->{$type} : $regexes->tag; + } + + private static function getRegexes() + { + if ( ! is_null(self::$regexes)) + { + return self::$regexes; + } + + $params = self::get(); + + // Tag character start and end + list($tag_start, $tag_end) = Params::getTagCharacters(); + $tag_start = RL_RegEx::quote($tag_start); + $tag_end = RL_RegEx::quote($tag_end); + + $pre = RL_PluginTag::getRegexSurroundingTagsPre(); + $post = RL_PluginTag::getRegexSurroundingTagsPost(); + $inside_tag = RL_PluginTag::getRegexInsideTag(); + + $spaces = RL_PluginTag::getRegexSpaces(); + $spaces_none = RL_PluginTag::getRegexSpaces('*'); + + $a_tag = RL_PluginTag::getRegexTags('a', false, false); + $spans_images = RL_PluginTag::getRegexTags(['span', 'i', 'img']); + $any_text = '[^<>]*'; + + self::$regexes = (object) []; + + self::$regexes->tag = + '(?' . $pre . ')' + . $tag_start . $params->tag . $spaces . '(?' . $inside_tag . ')' . $tag_end + . '(?' . $post . ')' + + . '(?
' . $pre . ')'
+			. '(?.*?)'
+			. '(?' . $post . ')'
+
+			. '(?' . $pre . ')'
+			. $tag_start . '\/' . $params->tag . $tag_end
+			. '(?' . $post . ')';
+
+		self::$regexes->inlink =
+			'(?' . $a_tag . ')'
+			. '(?
' . $any_text . ')'
+
+			. '(?(?:' . $spans_images . $any_text . '){0,6})'
+
+			. $tag_start . $params->tag . $spaces_none . '(?' . $inside_tag . ')' . $tag_end
+
+			. '(?.*?)'
+
+			. $tag_start . '\/' . $params->tag . $tag_end
+
+			. '(?(?:' . $any_text . $spans_images . '){0,6})'
+
+			. '(?' . $any_text . ')'
+			. '(?)';
+
+		self::$regexes->link = $a_tag;
+
+
+		return self::$regexes;
+	}
+
+	public static function getTagCharacters()
+	{
+		$params = self::get();
+
+		if ( ! isset($params->tag_character_start))
+		{
+			self::setTagCharacters();
+		}
+
+		return [$params->tag_character_start, $params->tag_character_end];
+	}
+
+	public static function setTagCharacters()
+	{
+		$params = self::get();
+
+		list(self::$params->tag_character_start, self::$params->tag_character_end) = explode('.', $params->tag_characters);
+	}
+}
diff --git a/deployed/regularlabs/plugins/system/modals/src/Pass.php b/deployed/regularlabs/plugins/system/modals/src/Pass.php
new file mode 100644
index 00000000..616c5a64
--- /dev/null
+++ b/deployed/regularlabs/plugins/system/modals/src/Pass.php
@@ -0,0 +1,172 @@
+
+ * @link            http://www.regularlabs.com
+ * @copyright       Copyright © 2018 Regular Labs All Rights Reserved
+ * @license         http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
+ */
+
+namespace RegularLabs\Plugin\System\Modals;
+
+defined('_JEXEC') or die;
+
+use RegularLabs\Library\RegEx as RL_RegEx;
+use RegularLabs\Library\StringHelper as RL_String;
+
+class Pass
+{
+	public static function passLinkChecks($attributes)
+	{
+		// return if the link has no href
+		if (empty($attributes->href))
+		{
+			return false;
+		}
+
+		$params = Params::get();
+
+		// return if the link already has the Modals main class
+		if ( ! empty($attributes->class) && in_array($params->class, explode(' ', $attributes->class)))
+		{
+			return false;
+		}
+
+		// return if url is in ignore list
+		if (self::urlIgnored($attributes->href))
+		{
+			return false;
+		}
+
+		// check for classnames, external sites and target blanks
+		if (
+			self::passClassnames($attributes)
+		)
+		{
+			return true;
+		}
+
+
+		return false;
+	}
+
+	public static function urlIgnored($url)
+	{
+		$params = Params::get();
+
+		if (empty($params->exclude_urls))
+		{
+			return false;
+		}
+
+		$exclude_urls = explode(',', str_replace(['\n', ' '], [',', ''], $params->exclude_urls));
+
+		foreach ($exclude_urls as $exclude)
+		{
+			if ($exclude && (strpos($url, $exclude) !== false || strpos(htmlentities($url), $exclude) !== false))
+			{
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	public static function passClassnames($attributes)
+	{
+		$params = Params::get();
+
+		if (empty($attributes->class) || empty($params->classnames))
+		{
+			return false;
+		}
+
+		$classnames = str_replace($params->class, '', $attributes->class);
+
+		return self::arrayInArray($classnames, $params->classnames);
+	}
+
+	private static function arrayInArray($needles, $haystack)
+	{
+		if ( ! is_array($needles))
+		{
+			$needles = explode(' ', trim($needles));
+		}
+		if ( ! is_array($haystack))
+		{
+			$haystack = explode(' ', trim($haystack));
+		}
+
+		// Check
+		return (boolean) array_intersect($haystack, $needles);
+	}
+
+	private static function passURLs($url)
+	{
+		$params = Params::get();
+
+		foreach ($params->urls as $param_url)
+		{
+			if (self::passURL($url, $param_url))
+			{
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	private static function passURL($url, $param_url)
+	{
+		$url = trim($url);
+		if (empty($url))
+		{
+			return false;
+		}
+
+		$param_url = trim($param_url);
+		if (empty($param_url))
+		{
+			return false;
+		}
+
+		$params = Params::get();
+
+		$urls = [$url, RL_String::html_entity_decoder($url)];
+
+		foreach ($urls as $url)
+		{
+			if ($params->urls_regex && self::passURLRegex($url, $param_url))
+			{
+				return true;
+			}
+
+			if ($params->urls_regex)
+			{
+				continue;
+			}
+
+			if (strpos($url, $param_url) !== false)
+			{
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	private static function passURLRegex($url, $param_url)
+	{
+		$url_part = str_replace(['#', '&'], ['\#', '(&|&)'], $param_url);
+
+		if ( ! RL_RegEx::match($url_part, $url))
+		{
+			return false;
+		}
+
+		return true;
+	}
+
+}
diff --git a/deployed/regularlabs/plugins/system/modals/src/Plugin.php b/deployed/regularlabs/plugins/system/modals/src/Plugin.php
new file mode 100644
index 00000000..2492dd3f
--- /dev/null
+++ b/deployed/regularlabs/plugins/system/modals/src/Plugin.php
@@ -0,0 +1,379 @@
+
+ * @link            http://www.regularlabs.com
+ * @copyright       Copyright © 2018 Regular Labs All Rights Reserved
+ * @license         http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
+ */
+
+/*
+ * This class is used as template (extend) for most Regular Labs plugins
+ * This class is not placed in the Regular Labs Library as a re-usable class because
+ * it also needs to be working when the Regular Labs Library is not installed
+ */
+
+namespace RegularLabs\Plugin\System\Modals;
+
+defined('_JEXEC') or die;
+
+if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php'))
+{
+	require_once JPATH_LIBRARIES . '/regularlabs/autoload.php';
+}
+
+use JFactory;
+use JInstaller;
+use JPlugin;
+use JPluginHelper;
+use JText;
+use ReflectionMethod;
+use RegularLabs\Library\Document as RL_Document;
+use RegularLabs\Library\Language as RL_Language;
+use RegularLabs\Library\Protect as RL_Protect;
+
+class Plugin extends JPlugin
+{
+	public $_alias       = '';
+	public $_title       = '';
+	public $_lang_prefix = '';
+
+	public $_has_tags              = false;
+	public $_enable_in_frontend    = true;
+	public $_enable_in_admin       = false;
+	public $_can_disable_by_url    = true;
+	public $_disable_on_components = false;
+	public $_protected_formats     = [];
+	public $_page_types            = [];
+
+	private $_init   = false;
+	private $_pass   = null;
+	private $_helper = null;
+
+	protected function run()
+	{
+		if ( ! $this->passChecks())
+		{
+			return false;
+		}
+
+		if ( ! $this->getHelper())
+		{
+			return false;
+		}
+
+		$caller = debug_backtrace()[1];
+
+		if (empty($caller))
+		{
+			return false;
+		}
+
+		$event = $caller['function'];
+
+		if ( ! method_exists($this->_helper, $event))
+		{
+			return false;
+		}
+
+		$reflect    = new ReflectionMethod($this->_helper, $event);
+		$parameters = $reflect->getParameters();
+
+		$arguments = [];
+
+		// Check if arguments should be passed as reference or not
+		foreach ($parameters as $count => $parameter)
+		{
+			if ($parameter->isPassedByReference())
+			{
+				$arguments[] = &$caller['args'][$count];
+				continue;
+			}
+			$arguments[] = $caller['args'][$count];
+		}
+
+		return call_user_func_array([$this->_helper, $event], $arguments);
+	}
+
+	/**
+	 * Create the helper object
+	 *
+	 * @return object|null The plugins helper object
+	 */
+	private function getHelper()
+	{
+		// Already initialized, so return
+		if ($this->_init)
+		{
+			return $this->_helper;
+		}
+
+		$this->_init = true;
+
+		RL_Language::load('plg_' . $this->_type . '_' . $this->_name);
+
+		$this->init();
+
+		$this->_helper = new Helper;
+
+		return $this->_helper;
+	}
+
+	private function passChecks()
+	{
+		if ( ! is_null($this->_pass))
+		{
+			return $this->_pass;
+		}
+
+		$this->_pass = false;
+
+		if ( ! $this->isFrameworkEnabled())
+		{
+			return false;
+		}
+
+		if ( ! self::passPageTypes())
+		{
+			return false;
+		}
+
+		// allow in frontend?
+		if ( ! $this->_enable_in_frontend
+			&& ! RL_Document::isAdmin())
+		{
+			return false;
+		}
+
+		// allow in admin?
+		if ( ! $this->_enable_in_admin
+			&& RL_Document::isAdmin()
+			&& ( ! isset(Params::get()->enable_admin) || ! Params::get()->enable_admin))
+		{
+			return false;
+		}
+
+		// disabled by url?
+		if ($this->_can_disable_by_url
+			&& RL_Protect::isDisabledByUrl($this->_alias))
+		{
+			return false;
+		}
+
+		// disabled by component?
+		if ($this->_disable_on_components
+			&& RL_Protect::isRestrictedComponent(isset(Params::get()->disabled_components) ? Params::get()->disabled_components : [], 'component'))
+		{
+			return false;
+		}
+
+		// restricted page?
+		if (RL_Protect::isRestrictedPage($this->_has_tags, $this->_protected_formats))
+		{
+			return false;
+		}
+
+		if ( ! $this->extraChecks())
+		{
+			return false;
+		}
+
+		$this->_pass = true;
+
+		return true;
+	}
+
+	public function passPageTypes()
+	{
+		if (empty($this->_page_types))
+		{
+			return true;
+		}
+
+		if (in_array('*', $this->_page_types))
+		{
+			return true;
+		}
+
+		if (empty(JFactory::$document))
+		{
+			return true;
+		}
+
+		if (RL_Document::isFeed())
+		{
+			return in_array('feed', $this->_page_types);
+		}
+
+		if (RL_Document::isPDF())
+		{
+			return in_array('pdf', $this->_page_types);
+		}
+
+		$page_type = JFactory::getDocument()->getType();
+
+		if (in_array($page_type, $this->_page_types))
+		{
+			return true;
+		}
+
+		return false;
+	}
+
+	public function extraChecks()
+	{
+		return true;
+	}
+
+	public function init()
+	{
+		return;
+	}
+
+	/**
+	 * Check if the Regular Labs Library is enabled
+	 *
+	 * @return bool
+	 */
+	private function isFrameworkEnabled()
+	{
+		if ( ! defined('REGULAR_LABS_LIBRARY_ENABLED'))
+		{
+			$this->setIsFrameworkEnabled();
+		}
+
+		if ( ! REGULAR_LABS_LIBRARY_ENABLED)
+		{
+			$this->throwError('REGULAR_LABS_LIBRARY_NOT_ENABLED');
+		}
+
+		return REGULAR_LABS_LIBRARY_ENABLED;
+	}
+
+	/**
+	 * Set the define with whether the Regular Labs Library is enabled
+	 */
+	private function setIsFrameworkEnabled()
+	{
+		// Return false if Regular Labs Library is not installed
+		if ( ! $this->isFrameworkInstalled())
+		{
+			define('REGULAR_LABS_LIBRARY_ENABLED', false);
+
+			return;
+		}
+
+		if ( ! JPluginHelper::isEnabled('system', 'regularlabs'))
+		{
+			$this->throwError('REGULAR_LABS_LIBRARY_NOT_ENABLED');
+
+			define('REGULAR_LABS_LIBRARY_ENABLED', false);
+
+			return;
+		}
+
+		define('REGULAR_LABS_LIBRARY_ENABLED', true);
+	}
+
+	/**
+	 * Check if the Regular Labs Library is installed
+	 *
+	 * @return bool
+	 */
+	private function isFrameworkInstalled()
+	{
+		if ( ! defined('REGULAR_LABS_LIBRARY_INSTALLED'))
+		{
+			$this->setIsFrameworkInstalled();
+		}
+
+		switch (REGULAR_LABS_LIBRARY_INSTALLED)
+		{
+			case 'outdated':
+				$this->throwError('REGULAR_LABS_LIBRARY_OUTDATED');
+
+				return false;
+
+			case 'no':
+				$this->throwError('REGULAR_LABS_LIBRARY_NOT_INSTALLED');
+
+				return false;
+
+			case 'yes':
+			default:
+				return true;
+		}
+	}
+
+	/**
+	 * set the define with whether the Regular Labs Library is installed
+	 */
+	private function setIsFrameworkInstalled()
+	{
+		if (
+			! is_file(JPATH_PLUGINS . '/system/regularlabs/regularlabs.xml')
+			|| ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')
+		)
+		{
+			define('REGULAR_LABS_LIBRARY_INSTALLED', 'no');
+
+			return;
+		}
+
+		$plugin  = JInstaller::parseXMLInstallFile(JPATH_PLUGINS . '/system/regularlabs/regularlabs.xml');
+		$library = JInstaller::parseXMLInstallFile(JPATH_LIBRARIES . '/regularlabs/regularlabs.xml');
+
+		if (empty($plugin) || empty($library))
+		{
+			define('REGULAR_LABS_LIBRARY_INSTALLED', 'no');
+
+			return;
+		}
+
+		if (version_compare($plugin['version'], '18.8.5928', '<')
+			|| version_compare($library['version'], '18.8.5928', '<'))
+		{
+			define('REGULAR_LABS_LIBRARY_INSTALLED', 'outdated');
+
+			return;
+		}
+
+		define('REGULAR_LABS_LIBRARY_INSTALLED', 'yes');
+	}
+
+	/**
+	 * Place an error in the message queue
+	 */
+	private function throwError($error)
+	{
+		// Return if page is not an admin page or the admin login page
+		if (
+			! JFactory::getApplication()->isClient('administrator')
+			|| JFactory::getUser()->get('guest')
+		)
+		{
+			return;
+		}
+
+		// load the admin language file
+		JFactory::getLanguage()->load('plg_' . $this->_type . '_' . $this->_name, JPATH_PLUGINS . '/' . $this->_type . '/' . $this->_name);
+
+		$text = JText::sprintf($this->_lang_prefix . '_' . $error, JText::_($this->_title));
+		$text = JText::_($text) . ' ' . JText::sprintf($this->_lang_prefix . '_EXTENSION_CAN_NOT_FUNCTION', JText::_($this->_title));
+
+		// Check if message is not already in queue
+		$messagequeue = JFactory::getApplication()->getMessageQueue();
+		foreach ($messagequeue as $message)
+		{
+			if ($message['message'] == $text)
+			{
+				return;
+			}
+		}
+
+		JFactory::getApplication()->enqueueMessage($text, 'error');
+	}
+}
+
diff --git a/deployed/regularlabs/plugins/system/modals/src/Protect.php b/deployed/regularlabs/plugins/system/modals/src/Protect.php
new file mode 100644
index 00000000..0be44a42
--- /dev/null
+++ b/deployed/regularlabs/plugins/system/modals/src/Protect.php
@@ -0,0 +1,50 @@
+
+ * @link            http://www.regularlabs.com
+ * @copyright       Copyright © 2018 Regular Labs All Rights Reserved
+ * @license         http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
+ */
+
+namespace RegularLabs\Plugin\System\Modals;
+
+defined('_JEXEC') or die;
+
+use RegularLabs\Library\Protect as RL_Protect;
+
+class Protect
+{
+	static $name = 'Modals';
+
+	public static function _(&$string)
+	{
+		RL_Protect::protectHtmlCommentTags($string);
+		RL_Protect::protectFields($string, Params::getTags(true));
+		RL_Protect::protectSourcerer($string);
+	}
+
+	public static function protectTags(&$string)
+	{
+		RL_Protect::protectTags($string, Params::getTags(true));
+	}
+
+	public static function unprotectTags(&$string)
+	{
+		RL_Protect::unprotectTags($string, Params::getTags(true));
+	}
+
+	/**
+	 * Wrap the comment in comment tags
+	 *
+	 * @param string $comment
+	 *
+	 * @return string
+	 */
+	public static function wrapInCommentTags($comment)
+	{
+		return RL_Protect::wrapInCommentTags(self::$name, $comment);
+	}
+}
diff --git a/deployed/regularlabs/plugins/system/modals/src/Replace.php b/deployed/regularlabs/plugins/system/modals/src/Replace.php
new file mode 100644
index 00000000..01a41e95
--- /dev/null
+++ b/deployed/regularlabs/plugins/system/modals/src/Replace.php
@@ -0,0 +1,374 @@
+
+ * @link            http://www.regularlabs.com
+ * @copyright       Copyright © 2018 Regular Labs All Rights Reserved
+ * @license         http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
+ */
+
+namespace RegularLabs\Plugin\System\Modals;
+
+defined('_JEXEC') or die;
+
+use JFactory;
+use RegularLabs\Library\Html as RL_Html;
+use RegularLabs\Library\Protect as RL_Protect;
+use RegularLabs\Library\RegEx as RL_RegEx;
+use RegularLabs\Library\StringHelper as RL_String;
+
+class Replace
+{
+	public static function replaceTags(&$string, $area = 'article', $context = '')
+	{
+		if ($area == 'article')
+		{
+			return false;
+		}
+
+		if ( ! is_string($string) || $string == '')
+		{
+			return false;
+		}
+
+		// Check if tags are in the text snippet used for the search component
+		if (strpos($context, 'com_search.') === 0)
+		{
+			$limit = explode('.', $context, 2);
+			$limit = (int) array_pop($limit);
+
+			$string_check = substr($string, 0, $limit);
+
+			if ( ! RL_String::contains($string_check, Params::getTags(true)))
+			{
+				return false;
+			}
+		}
+
+		$params = Params::get();
+
+		RL_Protect::removeFromHtmlTagAttributes(
+			$string,
+			[
+				$params->tag,
+			]
+		);
+
+		// allow in component?
+		if (RL_Protect::isRestrictedComponent(isset($params->disabled_components) ? $params->disabled_components : [], $area))
+		{
+
+			Protect::_($string);
+
+			$regex = Params::getRegex();
+
+			$string = RL_RegEx::replace($regex, '\4', $string);
+
+			Clean::cleanLeftoverJunk($string);
+
+			RL_Protect::unprotect($string);
+
+			return true;
+		}
+
+		Protect::_($string);
+
+		// Handle content inside the iframed modal
+		if (JFactory::getApplication()->input->getInt('ml', 0) && JFactory::getApplication()->input->getInt('iframe', 0))
+		{
+			self::replaceInsideModal($string);
+
+			Clean::cleanLeftoverJunk($string);
+
+			RL_Protect::unprotect($string);
+
+			return true;
+		}
+
+		self::replaceLinks($string);
+
+		// tag syntax inside links
+		self::replaceTagSyntaxInsideLinks($string);
+
+		list($start_tags, $end_tags) = Params::getTags();
+
+		list($pre_string, $string, $post_string) = RL_Html::getContentContainingSearches(
+			$string,
+			$start_tags,
+			$end_tags
+		);
+
+		// tag syntax
+		self::replaceTagSyntax($string);
+
+		$string = $pre_string . $string . $post_string;
+
+
+		Clean::cleanLeftoverJunk($string);
+
+		RL_Protect::unprotect($string);
+
+		return true;
+	}
+
+	// add ml to internal links
+	private static function replaceInsideModal(&$string)
+	{
+		self::replaceTagSyntax($string);
+
+		$regex = Params::getRegex('link');
+
+		RL_RegEx::matchAll($regex, $string, $matches);
+
+		if (empty($matches))
+		{
+			return;
+		}
+
+		foreach ($matches as $match)
+		{
+			// get the link attributes
+			$attributes = Link::getAttributeList($match[0]);
+
+			// ignore if the link has no href or is an anchor or has a target
+			if (empty($attributes->href) || $attributes->href[0] == '#' || isset($attributes->target))
+			{
+				continue;
+			}
+
+			// ignore if link is external or an image
+			if (File::isExternal($attributes->href) || File::isMedia($attributes->href))
+			{
+				continue;
+			}
+
+			$href = Document::addUrlAttributes($attributes->href, true);
+
+			self::replaceOnce('href="' . $href . '"', 'href="' . $attributes->href . '"', $string);
+		}
+	}
+
+	private static function replaceTagSyntaxInsideLinks(&$string)
+	{
+		$regex = Params::getRegex('inlink');
+
+		RL_RegEx::matchAll($regex, $string, $matches);
+
+		if (empty($matches))
+		{
+			return;
+		}
+
+		$params = Params::get();
+
+		foreach ($matches as $match)
+		{
+			$content = trim($match['image_pre'] . $match['text'] . $match['image_post']);
+
+			list($link, $extra) = Link::get($match['data'], $match['link_start'], $content);
+			$link .= '';
+
+			if ($params->place_comments)
+			{
+				$link = Protect::wrapInCommentTags($link);
+			}
+
+			self::replaceOnce($match[0], $link, $string, $extra);
+		}
+	}
+
+	private static function replaceTagSyntax(&$string)
+	{
+		$regex = Params::getRegex();
+
+		RL_RegEx::matchAll($regex, $string, $matches);
+
+		if (empty($matches))
+		{
+			return;
+		}
+
+		$params = Params::get();
+
+		foreach ($matches as $match)
+		{
+			$tags = RL_Html::cleanSurroundingTags(
+				[
+					'end_pre'    => $match['end_pre'],
+					'start_post' => $match['start_post'],
+				]
+			);
+			$tags = RL_Html::cleanSurroundingTags(
+				[
+					'end_pre'    => $tags['end_pre'],
+					'pre'        => $match['pre'],
+					'post'       => $match['post'],
+					'start_post' => $tags['start_post'],
+				],
+				['p']
+			);
+
+			list($link, $extra) = Link::get($match['data'], '', trim($tags['pre'] . $match['text'] . $tags['post']));
+
+			$link = $link . '';
+
+			if ($params->place_comments)
+			{
+				$link = Protect::wrapInCommentTags($link);
+			}
+
+			$html = $match['start_pre'] . $tags['start_post']
+				. $link
+				. $tags['end_pre'] . $match['end_post'];
+
+			self::replaceOnce($match[0], $html, $string, $extra);
+		}
+	}
+
+	private static function replaceLinks(&$string)
+	{
+		$params = Params::get();
+
+		if (
+			(
+				empty($params->classnames)
+				&& ! RL_RegEx::match('class\s*=\s*(?:"[^"]*|\'[^\']*)(?:' . implode('|', $params->classnames) . ')', $string)
+			)
+		)
+		{
+			return;
+		}
+
+		$regex = Params::getRegex('link');
+
+		RL_RegEx::matchAll($regex, $string, $matches);
+
+		if (empty($matches))
+		{
+			return;
+		}
+
+		foreach ($matches as $match)
+		{
+			self::replaceLink($string, $match);
+		}
+	}
+
+	private static function replaceLink(&$string, $match)
+	{
+		// get the link attributes
+		$attributes = Link::getAttributeList($match[0]);
+
+		if ( ! Pass::passLinkChecks($attributes))
+		{
+			return;
+		}
+
+		$data       = [];
+		$isexternal = File::isExternal($attributes->href);
+		$ismedia    = File::isMedia($attributes->href);
+		$iframe     = File::isIframe($attributes->href, $data);
+
+		// Find data-modal attributes set in html tag
+		foreach ($attributes as $key => $value)
+		{
+			if (strpos($key, 'data-modal-') !== 0)
+			{
+				continue;
+			}
+
+
+			// Remove the attribute from the attributes object
+			unset($attributes->{$key});
+		}
+
+		// Force/overrule certain data values
+		if ($iframe || ($isexternal && ! $ismedia))
+		{
+			// use iframe mode for external urls
+			$data['iframe'] = 'true';
+			Data::setDataWidthHeight($data, $isexternal);
+		}
+
+		$params = Params::get();
+
+		$attributes->class = ! empty($attributes->class) ? $attributes->class . ' ' . $params->class : $params->class;
+		$link              = Link::build($attributes, $data);
+
+		if ($params->place_comments)
+		{
+			$link = Protect::wrapInCommentTags($link);
+		}
+
+		self::replaceOnce($match[0], $link, $string);
+	}
+
+
+	private static function setImageAttributes(&$data, &$image_attributes, $image)
+	{
+		$params = Params::get();
+
+		$image_texts = Image::getImageTexts((array) $image_attributes, $image);
+
+		if ( ! $image_texts->title && $params->auto_titles)
+		{
+			$image_texts->title = File::getTitle($image->image, $params->title_case);
+		}
+		if ( ! $image_texts->thumbnail_title)
+		{
+			$image_texts->thumbnail_title = $image_texts->title;
+		}
+
+		if (isset($image_attributes->{'data-title'}))
+		{
+			$data['title'] = $image_attributes->{'data-title'};
+		}
+
+		if (isset($image_attributes->{'data-description'}))
+		{
+			$data['description'] = $image_attributes->{'data-description'};
+		}
+
+		if ($params->images_use_title_attribute && isset($image_attributes->title))
+		{
+			$key        = $params->images_use_title_attribute == 'description' ? 'description' : 'title';
+			$data[$key] = isset($data[$key]) ? $data[$key] : $image_attributes->title;
+		}
+
+		if ($params->images_use_alt_attribute && isset($image_attributes->alt))
+		{
+			$key        = $params->images_use_alt_attribute == 'description' ? 'description' : 'title';
+			$data[$key] = isset($data[$key]) ? $data[$key] : $image_attributes->alt;
+		}
+
+		$data['title']       = isset($data['title']) ? $data['title'] : $image_texts->title;
+		$data['alt']         = isset($data['title']) ? $data['title'] : $image_texts->alt;
+		$data['description'] = isset($data['description']) ? $data['description'] : $image_texts->description;
+
+		$image_attributes->title = $image_texts->thumbnail_title;
+		$image_attributes->alt   = $image_texts->thumbnail_alt;
+	}
+
+	/* <<< [PRO] <<< */
+
+	private static function replaceOnce($search, $replace, &$string, $extra = '')
+	{
+		if ( ! $extra
+			|| ! RL_RegEx::match(RL_RegEx::quote($search) . '(?.*?)', $string, $match)
+		)
+		{
+			$string = RL_String::replaceOnce($search, $replace . $extra, $string);
+
+			return;
+		}
+
+		// Place the extra div stuff behind the first ending div/p tag
+		$string = RL_String::replaceOnce(
+			$match[0],
+			$replace . $match['post'] . $extra,
+			$string
+		);
+	}
+}
diff --git a/deployed/regularlabs/plugins/system/modals/vendor/autoload.php b/deployed/regularlabs/plugins/system/modals/vendor/autoload.php
new file mode 100644
index 00000000..95473c30
--- /dev/null
+++ b/deployed/regularlabs/plugins/system/modals/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 = [];
+	private $prefixDirsPsr4    = [];
+	private $fallbackDirsPsr4  = [];
+
+	// PSR-0
+	private $prefixesPsr0     = [];
+	private $fallbackDirsPsr0 = [];
+
+	private $useIncludePath        = false;
+	private $classMap              = [];
+	private $classMapAuthoritative = false;
+	private $missingClasses        = [];
+	private $apcuPrefix;
+
+	public function getPrefixes()
+	{
+		if ( ! empty($this->prefixesPsr0))
+		{
+			return call_user_func_array('array_merge', $this->prefixesPsr0);
+		}
+
+		return [];
+	}
+
+	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') && ini_get('apc.enabled') ? $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([$this, 'loadClass'], true, $prepend);
+	}
+
+	/**
+	 * Unregisters this instance as an autoloader.
+	 */
+	public function unregister()
+	{
+		spl_autoload_unregister([$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]))
+				{
+					foreach ($this->prefixDirsPsr4[$search] as $dir)
+					{
+						$length = $this->prefixLengthsPsr4[$first][$search];
+						if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length)))
+						{
+							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/deployed/regularlabs/plugins/system/modals/vendor/composer/LICENSE b/deployed/regularlabs/plugins/system/modals/vendor/composer/LICENSE
new file mode 100644
index 00000000..f27399a0
--- /dev/null
+++ b/deployed/regularlabs/plugins/system/modals/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/deployed/regularlabs/plugins/system/modals/vendor/composer/autoload_classmap.php b/deployed/regularlabs/plugins/system/modals/vendor/composer/autoload_classmap.php
new file mode 100644
index 00000000..d708c05f
--- /dev/null
+++ b/deployed/regularlabs/plugins/system/modals/vendor/composer/autoload_classmap.php
@@ -0,0 +1,9 @@
+ [$baseDir . '/src'],
+];
diff --git a/deployed/regularlabs/plugins/system/modals/vendor/composer/autoload_real.php b/deployed/regularlabs/plugins/system/modals/vendor/composer/autoload_real.php
new file mode 100644
index 00000000..ccaa9dc3
--- /dev/null
+++ b/deployed/regularlabs/plugins/system/modals/vendor/composer/autoload_real.php
@@ -0,0 +1,60 @@
+= 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\ComposerStaticInitfb00be2768c44d809014f504788f7ef5::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);
+
+		return $loader;
+	}
+}
diff --git a/deployed/regularlabs/plugins/system/modals/vendor/composer/autoload_static.php b/deployed/regularlabs/plugins/system/modals/vendor/composer/autoload_static.php
new file mode 100644
index 00000000..edb96c0c
--- /dev/null
+++ b/deployed/regularlabs/plugins/system/modals/vendor/composer/autoload_static.php
@@ -0,0 +1,30 @@
+
+			[
+				'RegularLabs\\Plugin\\System\\Modals\\' => 33,
+			],
+	];
+
+	public static $prefixDirsPsr4 = [
+		'RegularLabs\\Plugin\\System\\Modals\\' =>
+			[
+				0 => __DIR__ . '/../..' . '/src',
+			],
+	];
+
+	public static function getInitializer(ClassLoader $loader)
+	{
+		return \Closure::bind(function () use ($loader) {
+			$loader->prefixLengthsPsr4 = ComposerStaticInitfb00be2768c44d809014f504788f7ef5::$prefixLengthsPsr4;
+			$loader->prefixDirsPsr4    = ComposerStaticInitfb00be2768c44d809014f504788f7ef5::$prefixDirsPsr4;
+		}, null, ClassLoader::class);
+	}
+}
diff --git a/deployed/regularlabs/plugins/system/modals/vendor/composer/installed.json b/deployed/regularlabs/plugins/system/modals/vendor/composer/installed.json
new file mode 100644
index 00000000..fe51488c
--- /dev/null
+++ b/deployed/regularlabs/plugins/system/modals/vendor/composer/installed.json
@@ -0,0 +1 @@
+[]
diff --git a/deployed/regularlabs/plugins/system/regularlabs/language/en-GB/en-GB.plg_system_regularlabs.ini b/deployed/regularlabs/plugins/system/regularlabs/language/en-GB/en-GB.plg_system_regularlabs.ini
new file mode 100644
index 00000000..63c40610
--- /dev/null
+++ b/deployed/regularlabs/plugins/system/regularlabs/language/en-GB/en-GB.plg_system_regularlabs.ini
@@ -0,0 +1,506 @@
+;; @package         Regular Labs Library
+;; @version         18.12.3953
+;; 
+;; @author          Peter van Westen 
+;; @link            http://www.regularlabs.com
+;; @copyright       Copyright © 2018 Regular Labs All Rights Reserved
+;; @license         http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
+;; 
+;; @translate       Want to help with translations? See: https://www.regularlabs.com/translate
+
+PLG_SYSTEM_REGULARLABS="System - Regular Labs Library"
+PLG_SYSTEM_REGULARLABS_DESC="Regular Labs Library - used by Regular Labs extensions"
+REGULAR_LABS_LIBRARY="Regular Labs Library"
+
+REGULAR_LABS_LIBRARY_DESC="[[%1:warning%]]The Regular Labs extensions need this plugin and will not function without it.

Regular Labs extensions include:[[%2:extensions%]]" +REGULAR_LABS_LIBRARY_DESC_WARNING="Do not uninstall or disable this plugin if you are using any Regular Labs extensions." + +COM_CONFIG_RL_ACTIONLOG_FIELDSET_LABEL="User Actions Log" +COM_MODULES_DESCRIPTION_FIELDSET_LABEL="Description" +COM_PLUGINS_DESCRIPTION_FIELDSET_LABEL="Description" +COM_PLUGINS_RL_BEHAVIOUR_FIELDSET_LABEL="Behaviour" +COM_PLUGINS_RL_DEFAULT_SETTINGS_FIELDSET_LABEL="Default Settings" +COM_PLUGINS_RL_MEDIA_FIELDSET_LABEL="Media" +COM_PLUGINS_RL_SETTINGS_ADMIN_MODULE_FIELDSET_LABEL="Administrator Module Options" +COM_PLUGINS_RL_SETTINGS_EDITOR_BUTTON_FIELDSET_LABEL="Editor Button Options" +COM_PLUGINS_RL_SETTINGS_SECURITY_FIELDSET_LABEL="Security Options" +COM_PLUGINS_RL_SETUP_FIELDSET_LABEL="Setup" +COM_PLUGINS_RL_STYLING_FIELDSET_LABEL="Styling" +COM_PLUGINS_RL_TAG_SYNTAX_FIELDSET_LABEL="Tag Syntax" + +RL_ACCESS_LEVELS="Access Levels" +RL_ACCESS_LEVELS_DESC="Select the access levels to assign to." +RL_ACTION_CHANGE_DEFAULT="Change Default" +RL_ACTION_CHANGE_STATE="Change Publish State" +RL_ACTION_CREATE="Create" +RL_ACTION_DELETE="Delete" +RL_ACTION_INSTALL="Install" +RL_ACTION_UNINSTALL="Uninstall" +RL_ACTION_UPDATE="Update" +RL_ACTIONLOG_EVENTS="Events To Log" +RL_ACTIONLOG_EVENTS_DESC="Select the actions to include in the User Actions Log." +RL_ADMIN="Admin" +RL_ADVANCED="Advanced" +RL_AKEEBASUBS="Akeeba Subscriptions" +RL_ALL="ALL" +RL_ALL_DESC="Will be published if ALL of below assignments are matched." +RL_ALL_RIGHTS_RESERVED="All Rights Reserved" +RL_ALSO_ON_CHILD_ITEMS="Also on child items" +RL_ALSO_ON_CHILD_ITEMS_DESC="Also assign to child items of the selected items?" +RL_ALSO_ON_CHILD_ITEMS_MENUITEMS_DESC="The child items refer to actual sub-items in the above selection. They do not refer to links on selected pages." +RL_ANY="ANY" +RL_ANY_DESC="Will be published if ANY (one or more) of below assignments are matched.
Assignment groups where 'Ignore' is selected will be ignored." +RL_ARE_YOU_SURE="Are you sure?" +RL_ARTICLE="Article" +RL_ARTICLE_AUTHORS="Authors" +RL_ARTICLE_AUTHORS_DESC="Select the authors to assign to." +RL_ARTICLES="Articles" +RL_ARTICLES_DESC="Select the articles to assign to." +RL_AS_EXPORTED="As exported" +RL_ASSIGNMENTS="Assignments" +RL_ASSIGNMENTS_DESC="By selecting the specific assignments you can limit where this %s should or shouldn't be published.
To have it published on all pages, simply do not specify any assignments." +RL_AUSTRALIA="Australia" +RL_AUTHORS="Authors" +RL_AUTO="Auto" +RL_BEHAVIOR="Behaviour" +RL_BEHAVIOUR="Behaviour" +RL_BOOTSTRAP="Bootstrap" +RL_BOOTSTRAP_FRAMEWORK_DISABLED="You have disabled the Bootstrap Framework to be initiated. %s needs the Bootstrap Framework to function. Make sure your template or other extensions load the necessary scripts to replace the required functionality." +RL_BOTH="Both" +RL_BOTTOM="Bottom" +RL_BROWSERS="Browsers" +RL_BROWSERS_DESC="Select the browsers to assign to. Keep in mind that browser detection is not always 100% accurate. Users can setup their browser to mimic other browsers" +RL_BUTTON_ICON="Button Icon" +RL_BUTTON_ICON_DESC="Select which icon to show in the button." +RL_BUTTON_TEXT="Button Text" +RL_BUTTON_TEXT_DESC="This text will be shown in the Editor Button." +RL_CACHE_TIME="Cache Time" +RL_CACHE_TIME_DESC="The maximum length of time in minutes for a cache file to be stored before it is refreshed. Leave empty to use the global setting." +RL_CATEGORIES="Categories" +RL_CATEGORIES_DESC="Select the categories to assign to." +RL_CHANGELOG="Changelog" +RL_CLASSNAME="CSS Class" +RL_COLLAPSE="Collapse" +RL_COM="Component" +RL_COMBINE_ADMIN_MENU="Combine Admin Menu" +RL_COMBINE_ADMIN_MENU_DESC="Select to combine all Regular Labs - components into a submenu in the administrator menu." +RL_COMPONENTS="Components" +RL_COMPONENTS_DESC="Select the components to assign to." +RL_CONTENT="Content" +RL_CONTENT_KEYWORDS="Content Keywords" +RL_CONTENT_KEYWORDS_DESC="Enter the keywords found in the content to assign to. Use commas to separate the keywords." +RL_CONTINENTS="Continents" +RL_CONTINENTS_DESC="Select the continents to assign to." +RL_COOKIECONFIRM="Cookie Confirm" +RL_COOKIECONFIRM_COOKIES="Cookies allowed" +RL_COOKIECONFIRM_COOKIES_DESC="Assign to whether cookies are allowed or disallowed, based on the configuration of Cookie Confirm (by Twentronix) and the visitor's choice to accept or decline cookies." +RL_COPY_OF="Copy of %s" +RL_COPYRIGHT="Copyright" +RL_COUNTRIES="Countries" +RL_COUNTRIES_DESC="Select the countries to assign to." +RL_CSS_CLASS="Class (CSS)" +RL_CSS_CLASS_DESC="Define a css class name for styling purposes." +RL_CURRENT="Current" +RL_CURRENT_DATE="Current date/time: %s" +RL_CURRENT_VERSION="Your current version is %s" +RL_CUSTOM_CODE="Custom Code" +RL_CUSTOM_CODE_DESC="Enter the code the Editor Button should insert into the content (instead of the default code)." +RL_CUSTOM_FIELD="Custom Field" +RL_CUSTOM_FIELDS="Custom Fields" +RL_DATE="Date" +RL_DATE_RECURRING="Recurring" +RL_DATE_RECURRING_DESC="Select to apply date range every year. (So the year in the selection will be ignored)" +RL_DATE_TIME="Date & Time" +RL_DATE_TIME_DESC="The date and time assignments use the date/time of your servers, not that of the visitors system." +RL_DAYS="Days of the week" +RL_DAYS_DESC="Select days of the week to assign to." +RL_DEFAULT_ORDERING="Default Ordering" +RL_DEFAULT_ORDERING_DESC="Set the default ordering of the list items" +RL_DEFAULT_SETTINGS="Default Settings" +RL_DEFAULTS="Defaults" +RL_DEVICE_DESKTOP="Desktop" +RL_DEVICE_MOBILE="Mobile" +RL_DEVICE_TABLET="Tablet" +RL_DEVICES="Devices" +RL_DEVICES_DESC="Select the devices to assign to. Keep in mind that device detection is not always 100% accurate. Users can setup their device to mimic other devices" +RL_DIRECTION="Direction" +RL_DIRECTION_DESC="Select the direction" +RL_DISABLE_ON_ADMIN_COMPONENTS_DESC="Select in which administrator components NOT to enable the use of this extension." +RL_DISABLE_ON_ALL_COMPONENTS_DESC="Select in which components NOT to enable the use of this extension." +RL_DISABLE_ON_COMPONENTS="Disable on Components" +RL_DISABLE_ON_COMPONENTS_DESC="Select in which frontend components NOT to enable the use of this extension." +RL_DISPLAY_EDITOR_BUTTON="Display Editor Button" +RL_DISPLAY_EDITOR_BUTTON_DESC="Select to display an editor button." +RL_DISPLAY_LINK="Display link" +RL_DISPLAY_LINK_DESC="How do you want the link to be displayed?" +RL_DISPLAY_TOOLBAR_BUTTON="Display Toolbar Button" +RL_DISPLAY_TOOLBAR_BUTTON_DESC="Select to show a button in the toolbar." +RL_DISPLAY_TOOLTIP="Display Tooltip" +RL_DISPLAY_TOOLTIP_DESC="Select to display a tooltip with extra info when mouse hovers over link/icon." +RL_EASYBLOG="EasyBlog" +RL_ENABLE="Enable" +RL_ENABLE_ACTIONLOG="Log User Actions" +RL_ENABLE_ACTIONLOG_DESC="Select to store User Actions. These actions will be visible in the User Actions Log module." +RL_ENABLE_IN="Enable in" +RL_ENABLE_IN_ADMIN="Enable in administrator" +RL_ENABLE_IN_ADMIN_DESC="If enabled, the plugin will also work in the administrator side of the website.

Normally you will not need this. And it can cause unwanted effects, like slowing down the administrator and the plugin tags being handled in areas you don't want it." +RL_ENABLE_IN_ARTICLES="Enable in articles" +RL_ENABLE_IN_COMPONENTS="Enable in components" +RL_ENABLE_IN_DESC="Select whether to enable in the frontend or administrator side or both." +RL_ENABLE_IN_FRONTEND="Enable in frontend" +RL_ENABLE_IN_FRONTEND_DESC="If enabled, it will also be available in the frontend." +RL_ENABLE_OTHER_AREAS="Enable other areas" +RL_EXCLUDE="Exclude" +RL_EXPAND="Expand" +RL_EXPORT="Export" +RL_EXPORT_FORMAT="Export Format" +RL_EXPORT_FORMAT_DESC="Select the file format for the export files." +RL_EXTRA_PARAMETERS="Extra Parameters" +RL_EXTRA_PARAMETERS_DESC="Enter any extra parameters that cannot be set with the available settings" +RL_FALL="Fall / Autumn" +RL_FEATURES="Features" +RL_FIELD_NAME="Field Name" +RL_FIELD_PARAM_MULTIPLE="Multiple" +RL_FIELD_PARAM_MULTIPLE_DESC="Allow multiple values to be selected." +RL_FIELD_VALUE="Field Value" +RL_FILES_NOT_FOUND="Required %s files not found!" +RL_FILTERS="Filters" +RL_FINISH_PUBLISHING="Finish Publishing" +RL_FINISH_PUBLISHING_DESC="Enter the date to end publishing" +RL_FIX_HTML="Fix HTML" +RL_FIX_HTML_DESC="Select to let the extension fix any html structure issues it finds. This is often necessary to deal with surrounding html tags.

Only switch this off if you have issues with this." +RL_FLEXICONTENT="FLEXIcontent" +RL_FOR_MORE_GO_PRO="For more functionality you can purchase the PRO version." +RL_FORM2CONTENT="Form2Content" +RL_FRAMEWORK_NO_LONGER_USED="The Old NoNumber Framework does not seem to be used by any other extensions you have installed. It is probably safe to disable or uninstall this plugin." +RL_FRONTEND="Frontend" +RL_GALLERY="Gallery" +RL_GEO="Geolocating" +RL_GEO_DESC="Geolocating is not always 100% accurate. The geolocation is based on the IP address of the visitor. Not all IP addresses are fixed or known." +RL_GEO_GEOIP_COPYRIGHT_DESC="This product includes GeoLite2 data created by MaxMind, available from [[%1:link%]]" +RL_GEO_NO_GEOIP_LIBRARY="The Regular Labs GeoIP library is not installed. You need to [[%1:link start%]]install the Regular Labs GeoIP library[[%2:link end%]] to be able to use the Geolocating assignments." +RL_GO_PRO="Go Pro!" +RL_HEADING_1="Heading 1" +RL_HEADING_2="Heading 2" +RL_HEADING_3="Heading 3" +RL_HEADING_4="Heading 4" +RL_HEADING_5="Heading 5" +RL_HEADING_6="Heading 6" +RL_HEADING_ACCESS_ASC="Access ascending" +RL_HEADING_ACCESS_DESC="Access descending" +RL_HEADING_CATEGORY_ASC="Category ascending" +RL_HEADING_CATEGORY_DESC="Category descending" +RL_HEADING_CLIENTID_ASC="Location ascending" +RL_HEADING_CLIENTID_DESC="Location descending" +RL_HEADING_COLOR_ASC="Colour ascending" +RL_HEADING_COLOR_DESC="Colour descending" +RL_HEADING_DEFAULT_ASC="Default ascending" +RL_HEADING_DEFAULT_DESC="Default descending" +RL_HEADING_DESCRIPTION_ASC="Description ascending" +RL_HEADING_DESCRIPTION_DESC="Description descending" +RL_HEADING_ID_ASC="ID ascending" +RL_HEADING_ID_DESC="ID descending" +RL_HEADING_LANGUAGE_ASC="Language ascending" +RL_HEADING_LANGUAGE_DESC="Language descending" +RL_HEADING_ORDERING_ASC="Ordering ascending" +RL_HEADING_ORDERING_DESC="Ordering descending" +RL_HEADING_PAGES_ASC="Menu Items ascending" +RL_HEADING_PAGES_DESC="Menu Items descending" +RL_HEADING_POSITION_ASC="Position ascending" +RL_HEADING_POSITION_DESC="Position descending" +RL_HEADING_STATUS_ASC="Status ascending" +RL_HEADING_STATUS_DESC="Status descending" +RL_HEADING_STYLE_ASC="Style ascending" +RL_HEADING_STYLE_DESC="Style descending" +RL_HEADING_TEMPLATE_ASC="Template ascending" +RL_HEADING_TEMPLATE_DESC="Template descending" +RL_HEADING_TITLE_ASC="Title ascending" +RL_HEADING_TITLE_DESC="Title descending" +RL_HEADING_TYPE_ASC="Type ascending" +RL_HEADING_TYPE_DESC="Type descending" +RL_HEIGHT="Height" +RL_HEMISPHERE="Hemisphere" +RL_HEMISPHERE_DESC="Select the hemisphere your website is located in" +RL_HIGH="High" +RL_HIKASHOP="HikaShop" +RL_HOME_PAGE="Home Page" +RL_HOME_PAGE_DESC="Unlike selecting the home page (default) item via the Menu Items, this will only match the real home page, not any URL that has the same Itemid as the home menu item.

This might not work for all 3rd party SEF extensions." +RL_HTML_LINK="[[%1:text%]]" +RL_ICON_ONLY="Icon only" +RL_IGNORE="Ignore" +RL_IMAGE="Image" +RL_IMAGE_ALT="Image Alt" +RL_IMAGE_ALT_DESC="The Alt value of the image." +RL_IMAGE_ATTRIBUTES="Image Attributes" +RL_IMAGE_ATTRIBUTES_DESC="The extra attributes of the image, like: alt="My image" width="300"" +RL_IMPORT="Import" +RL_IMPORT_ITEMS="Import Items" +RL_INCLUDE="Include" +RL_INCLUDE_CHILD_ITEMS="Include child items" +RL_INCLUDE_CHILD_ITEMS_DESC="Also include child items of the selected items?" +RL_INCLUDE_NO_ITEMID="Include no Itemid" +RL_INCLUDE_NO_ITEMID_DESC="Also assign when no menu Itemid is set in URL?" +RL_INITIALISE_EVENT="Initialise on Event" +RL_INITIALISE_EVENT_DESC="Set the internal Joomla event on which the plugin should be initialised. Only change this if you experience issues with the plugin not working." +RL_INSERT="Insert" +RL_INSERT_DATE_NAME="Insert Date / Name" +RL_IP_RANGES="IP Addresses / Ranges" +RL_IP_RANGES_DESC="A comma and/or enter separated list of IP addresses and IP ranges. For instance:
127.0.0.1
128.0-128.1
129" +RL_IPS="IP Addresses" +RL_IS_FREE_VERSION="This is the FREE version of %s." +RL_ITEM="Item" +RL_ITEM_IDS="Item IDs" +RL_ITEM_IDS_DESC="Enter the item ids to assign to. Use commas to separate the ids." +RL_ITEMS="Items" +RL_ITEMS_DESC="Select the items to assign to." +RL_JCONTENT="Joomla! Content" +RL_JED_REVIEW="Like this extension? [[%1:start link%]]Leave a review at the JED[[%2:end link%]]" +RL_JOOMLA2_VERSION_ON_JOOMLA3="You are running a Joomla 2.5 version of %1$s on Joomla 3. Please reinstall %1$s to fix the problem." +RL_JQUERY_DISABLED="You have disabled the jQuery script. %s needs jQuery to function. Make sure your template or other extensions load the necessary scripts to replace the required functionality." +RL_K2="K2" +RL_K2_CATEGORIES="K2 Categories" +RL_LANGUAGE="Language" +RL_LANGUAGE_DESC="Select the language to assign to." +RL_LANGUAGES="Languages" +RL_LANGUAGES_DESC="Select the languages to assign to." +RL_LAYOUT="Layout" +RL_LAYOUT_DESC="Select the layout to use. You can override this layout in the component or template." +RL_LEVELS="Levels" +RL_LEVELS_DESC="Select the levels to assign to." +RL_LIB="Library" +RL_LINK_TEXT="Link Text" +RL_LINK_TEXT_DESC="The text to display as link." +RL_LIST="List" +RL_LOAD_BOOTSTRAP_FRAMEWORK="Load Bootstrap Framework" +RL_LOAD_BOOTSTRAP_FRAMEWORK_DESC="Disable to not initiate the Bootstrap Framework." +RL_LOAD_JQUERY="Load jQuery Script" +RL_LOAD_JQUERY_DESC="Select to load the core jQuery script. You can disable this if you experience conflicts if your template or other extensions load their own version of jQuery." +RL_LOAD_MOOTOOLS="Load Core MooTools" +RL_LOAD_MOOTOOLS_DESC="Select to load the core MooTools script. You can disable this if you experience conflicts if your template or other extensions load their own version of MooTools." +RL_LOAD_STYLESHEET="Load Stylesheet" +RL_LOAD_STYLESHEET_DESC="Select to load the extensions stylesheet. You can disable this if you place all your own styles in some other stylesheet, like the templates stylesheet." +RL_LOW="Low" +RL_LTR="Left-to-Right" +RL_MATCH_ALL="Match All" +RL_MATCH_ALL_DESC="Select to only let the assignment pass if all of the selected items are matched." +RL_MATCHING_METHOD="Matching Method" +RL_MATCHING_METHOD_DESC="Should all or any assignments be matched?

[[%1:all%]]
[[%2:all description%]]

[[%3:any%]]
[[%4:any description%]]" +RL_MAX_LIST_COUNT="Maximum List Count" +RL_MAX_LIST_COUNT_DESC="The maximum number of elements to show in the multi-select lists. If the total number of items is higher, the selection field will be displayed as a text field.

You can set this number lower if you experience long pageloads due to high number of items in lists." +RL_MAX_LIST_COUNT_INCREASE="Increase Maximum List Count" +RL_MAX_LIST_COUNT_INCREASE_DESC="There are more than [[%1:max%]] items.

To prevent slow pages this field is displayed as a textarea instead of a dynamic select list.

You can increase the '[[%2:max setting%]]' in the Regular Labs Library plugin settings." +RL_MAXIMIZE="Maximize" +RL_MEDIA_VERSIONING="Use Media Versioning" +RL_MEDIA_VERSIONING_DESC="Select to add the extension version number to the end of media (js/css) urls, to make browsers force load the correct file." +RL_MEDIUM="Medium" +RL_MENU_ITEMS="Menu Items" +RL_MENU_ITEMS_DESC="Select the menu items to assign to." +RL_META_KEYWORDS="Meta Keywords" +RL_META_KEYWORDS_DESC="Enter the keywords found in the meta keywords to assign to. Use commas to separate the keywords." +RL_MIJOSHOP="MijoShop" +RL_MINIMIZE="Minimize" +RL_MOBILE_BROWSERS="Mobile Browsers" +RL_MOD="Module" +RL_MONTHS="Months" +RL_MONTHS_DESC="Select months to assign to." +RL_MORE_INFO="More info" +RL_N_ITEMS_ARCHIVED="%s items archived." +RL_N_ITEMS_ARCHIVED_1="%s item archived." +RL_N_ITEMS_CHECKED_IN_0="No items checked in." +RL_N_ITEMS_CHECKED_IN_1="%d item checked in." +RL_N_ITEMS_CHECKED_IN_MORE="%d items checked in." +RL_N_ITEMS_DELETED="%s items deleted." +RL_N_ITEMS_DELETED_1="%s item deleted." +RL_N_ITEMS_FEATURED="%s items featured." +RL_N_ITEMS_FEATURED_1="%s item featured." +RL_N_ITEMS_PUBLISHED="%s items published." +RL_N_ITEMS_PUBLISHED_1="%s item published." +RL_N_ITEMS_TRASHED="%s items trashed." +RL_N_ITEMS_TRASHED_1="%s item trashed." +RL_N_ITEMS_UNFEATURED="%s items unfeatured." +RL_N_ITEMS_UNFEATURED_1="%s item unfeatured." +RL_N_ITEMS_UNPUBLISHED="%s items unpublished." +RL_N_ITEMS_UNPUBLISHED_1="%s item unpublished." +RL_N_ITEMS_UPDATED="%d items updated." +RL_N_ITEMS_UPDATED_1="One item has been updated" +RL_NEW_CATEGORY="Create New Category" +RL_NEW_CATEGORY_ENTER="Enter a new category name" +RL_NEW_VERSION_AVAILABLE="A new version is available" +RL_NEW_VERSION_OF_AVAILABLE="A new version of %s is available" +RL_NO_ICON="No icon" +RL_NO_ITEMS_FOUND="No items found." +RL_NORMAL="Normal" +RL_NORTHERN="Northern" +RL_NOT="Not" +RL_ONLY="Only" +RL_ONLY_AVAILABLE_IN_JOOMLA="Only available in Joomla %s or higher." +RL_ONLY_AVAILABLE_IN_PRO="Only available in PRO version!" +RL_ONLY_AVAILABLE_IN_PRO_LIST_OPTION="(Only available in PRO version)" +RL_ONLY_VISIBLE_TO_ADMIN="This message will only be displayed to (Super) Administrators." +RL_OPTION_SELECT="- Select -" +RL_OPTION_SELECT_CLIENT="- Select Client -" +RL_OS="Operating Systems" +RL_OS_DESC="Select the operating systems to assign to. Keep in mind that operating system detection is not always 100% accurate. Users can setup their browser to mimic other operating systems." +RL_OTHER_AREAS="Other Areas" +RL_OTHER_OPTIONS="Other Options" +RL_OTHER_SETTINGS="Other Settings" +RL_OTHERS="Others" +RL_PAGE_TYPES="Page types" +RL_PAGE_TYPES_DESC="Select on what page types the assignment should be active." +RL_PHP="Custom PHP" +RL_PHP_DESC="Enter a piece of PHP code to evaluate. The code must return the value true or false.

For instance:

[[%1:code%]]" +RL_PLACE_HTML_COMMENTS="Place HTML comments" +RL_PLACE_HTML_COMMENTS_DESC="By default HTML comments are placed around the output of this extension.

These comments can help you troubleshoot when you don't get the output you expect.

If you prefer to not have these comments in your HTML output, turn this option off." +RL_PLG_ACTIONLOG="Action Log Plugin" +RL_PLG_EDITORS-XTD="Editor Button Plugin" +RL_PLG_FIELDS="Field Plugin" +RL_PLG_SYSTEM="System Plugin" +RL_POSTALCODES="Postal Codes" +RL_POSTALCODES_DESC="A comma separated list of postal codes (12345) or postal code ranges (12300-12500).
This can only be used for [[%1:start link%]]a limited number of countries and IP addresses[[%2:end link%]]." +RL_POWERED_BY="Powered by %s" +RL_PRODUCTS="Products" +RL_PUBLISHED_DESC="You can use this to (temporarily) disable this item." +RL_PUBLISHING_ASSIGNMENTS="Publishing Assignments" +RL_PUBLISHING_SETTINGS="Publish items" +RL_RANDOM="Random" +RL_REDSHOP="RedShop" +RL_REGIONS="Regions / States" +RL_REGIONS_DESC="Select the regions / states to assign to." +RL_REGULAR_EXPRESSIONS="Use Regular Expressions" +RL_REGULAR_EXPRESSIONS_DESC="Select to treat the value as regular expressions." +RL_REMOVE_IN_DISABLED_COMPONENTS="Remove in Disabled Components" +RL_REMOVE_IN_DISABLED_COMPONENTS_DESC="If selected, the plugin syntax will get removed from the component. If not, the original plugins syntax will remain intact." +RL_RESIZE_IMAGES="Resize Images" +RL_RESIZE_IMAGES_CROP="Crop" +RL_RESIZE_IMAGES_CROP_DESC="Select to make the resized image crop the original image.
If selected, the resized image will always have the set width and height.
If not selected, the resized image will be resized to the maximum width or height maintaining its aspect ratio." +RL_RESIZE_IMAGES_DESC="If selected, resized images will be automatically created for images if they do not exist yet. The resized images will be created using below settings." +RL_RESIZE_IMAGES_FILETYPES="Only on Filetypes" +RL_RESIZE_IMAGES_FILETYPES_DESC="Select the filetypes to do resizing on." +RL_RESIZE_IMAGES_FOLDER="Folder" +RL_RESIZE_IMAGES_FOLDER_DESC="The folder containing the resized images. This will be a subfolder of the folder containing your original images." +RL_RESIZE_IMAGES_HEIGHT_DESC="Set the height of the resized image in pixels (ie 180)." +RL_RESIZE_IMAGES_NO_HEIGHT_DESC="The Height will be calculated based on the Width defined above and the aspect ratio of the original image." +RL_RESIZE_IMAGES_NO_WIDTH_DESC="The Width will be calculated based on the Height defined below and the aspect ratio of the original image." +RL_RESIZE_IMAGES_QUALITY="JPG Quality" +RL_RESIZE_IMAGES_QUALITY_DESC="The quality of the resized images. Choose from Low, Medium or High. The higher the quality, the larger the resulting files.
This only affects jpeg images." +RL_RESIZE_IMAGES_USE_WIDTH_OR_HEIGHT="Set" +RL_RESIZE_IMAGES_USE_WIDTH_OR_HEIGHT_DESC="Select whether to resize images using the maximum width or height." +RL_RESIZE_IMAGES_WIDTH_DESC="Set the width of the resized image in pixels (ie 320)." +RL_RTL="Right-to-Left" +RL_SAVE_CONFIG="After saving the Options it will not pop up on page load anymore." +RL_SEASONS="Seasons" +RL_SEASONS_DESC="Select seasons to assign to." +RL_SELECT="Select" +RL_SELECT_A_CATEGORY="Select a Category" +RL_SELECT_ALL="Select all" +RL_SELECT_AN_ARTICLE="Select an Article" +RL_SELECTED="Selected" +RL_SELECTION="Selection" +RL_SELECTION_DESC="Select whether to include or exclude the selection for the assignment.

Include
Publish only on selection.

Exclude
Publish everywhere except on selection." +RL_SETTINGS_ADMIN_MODULE="Administrator Module Options" +RL_SETTINGS_EDITOR_BUTTON="Editor Button Options" +RL_SETTINGS_SECURITY="Security Options" +RL_SHOW_ASSIGNMENTS="Show Assignments" +RL_SHOW_ASSIGNMENTS_DESC="Select whether to only show the selected assignments. You can use this to get a clean overview of the active assignments." +RL_SHOW_ASSIGNMENTS_SELECTED_DESC="All not-selected assignment types are now hidden from view." +RL_SHOW_COPYRIGHT="Show Copyright" +RL_SHOW_COPYRIGHT_DESC="If selected, extra copyright info will be displayed in the admin views. Regular Labs extensions never show copyright info or backlinks on the frontend." +RL_SHOW_HELP_MENU="Show Help Menu Item" +RL_SHOW_HELP_MENU_DESC="Select to show a link to the Regular Labs website in the Administrator Help menu." +RL_SHOW_ICON="Show Button Icon" +RL_SHOW_ICON_DESC="If selected, the icon will be displayed in the Editor Button." +RL_SHOW_UPDATE_NOTIFICATION="Show Update Notification" +RL_SHOW_UPDATE_NOTIFICATION_DESC="If selected, an update notification will be shown in the main component view when there is a new version for this extension." +RL_SIMPLE="Simple" +RL_SLIDES="Slides" +RL_SOUTHERN="Southern" +RL_SPRING="Spring" +RL_START="Start" +RL_START_PUBLISHING="Start Publishing" +RL_START_PUBLISHING_DESC="Enter the date to start publishing" +RL_STRIP_SURROUNDING_TAGS="Strip Surrounding Tags" +RL_STRIP_SURROUNDING_TAGS_DESC="Select to always remove html tags (div, p, span) surrounding the plugin tag. If switched off, the plugin will try to remove tags that break the html structure (like p inside p tags)." +RL_STYLING="Styling" +RL_SUMMER="Summer" +RL_TABLE_NOT_FOUND="Required %s database table not found!" +RL_TABS="Tabs" +RL_TAG_CHARACTERS="Tag Characters" +RL_TAG_CHARACTERS_DESC="The surrounding characters of the tag syntax.

Note: If you change this, all existing tags will not work anymore." +RL_TAG_SYNTAX="Tag Syntax" +RL_TAG_SYNTAX_DESC="The word to be used in the tags.

Note: If you change this, all existing tags will not work anymore." +RL_TAGS="Tags" +RL_TAGS_DESC="Enter the tags to assign to. Use commas to separate the tags." +RL_TEMPLATES="Templates" +RL_TEMPLATES_DESC="Select the templates to assign to." +RL_TEXT="Text" +RL_TEXT_HTML="Text (HTML)" +RL_TEXT_ONLY="Text only" +RL_THIS_EXTENSION_NEEDS_THE_MAIN_EXTENSION_TO_FUNCTION="This extension needs %s to function correctly!" +RL_TIME="Time" +RL_TIME_FINISH_PUBLISHING_DESC="Enter the time to end publishing.

Format: 23:59" +RL_TIME_START_PUBLISHING_DESC="Enter the time to start publishing.

Format: 23:59" +RL_TOGGLE="Toggle" +RL_TOOLTIP="Tooltip" +RL_TOP="Top" +RL_TOTAL="Total" +RL_TYPES="Types" +RL_TYPES_DESC="Select the types to assign to." +RL_UNSELECT_ALL="Unselect All" +RL_UNSELECTED="Unselected" +RL_UPDATE_TO="Update to version %s" +RL_URL="URL" +RL_URL_PARTS="URL matches" +RL_URL_PARTS_DESC="Enter (part of) the URLs to match.
Use a new line for each different match." +RL_URL_PARTS_REGEX="Url parts will be matched using regular expressions. So make sure the string uses valid regex syntax." +RL_USE_CONTENT_ASSIGNMENTS="For category & article (item) assignments, see the above Joomla! Content section." +RL_USE_CUSTOM_CODE="Use Custom Code" +RL_USE_CUSTOM_CODE_DESC="If selected, the Editor Button will insert the given custom code instead." +RL_USE_SIMPLE_BUTTON="Use Simple Button" +RL_USE_SIMPLE_BUTTON_DESC="Select to use a simple insert button, that simply inserts some example syntax into the editor." +RL_USER_GROUP_LEVELS="User Group Levels" +RL_USER_GROUPS="User Groups" +RL_USER_GROUPS_DESC="Select the user groups to assign to." +RL_USER_IDS="User IDs" +RL_USER_IDS_DESC="Enter the user ids to assign to. Use commas to separate ids." +RL_USERS="Users" +RL_UTF8="UTF-8" +RL_VIDEO="Video" +RL_VIEW="View" +RL_VIEW_DESC="Select what default view should be used when creating a new item." +RL_VIRTUEMART="VirtueMart" +RL_WIDTH="Width" +RL_WINTER="Winter" +RL_ZOO="ZOO" +RL_ZOO_CATEGORIES="ZOO Categories" + +;; NO NEED TO TRANSLATE THESE +ADD_TO_MENU="Add to Menu" +ADVANCED_MODULE_MANAGER="Advanced Module Manager" +ADVANCED_TEMPLATE_MANAGER="Advanced Template Manager" +ARTICLES_ANYWHERE="Articles Anywhere" +ARTICLES_FIELD="Articles Field" +BETTER_PREVIEW="Better Preview" +BETTER_TRASH="Better Trash" +CACHE_CLEANER="Cache Cleaner" +CDN_FOR_JOOMLA="CDN for Joomla!" +COMPONENTS_ANYWHERE="Components Anywhere" +CONDITIONAL_CONTENT="Conditional Content" +CONTENT_TEMPLATER="Content Templater" +DB_REPLACER="DB Replacer" +DUMMY_CONTENT="Dummy Content" +EMAIL_PROTECTOR="Email Protector" +REGULAR_LABS_EXTENSION_MANAGER="Regular Labs Extension Manager" +GEOIP="GeoIP" +IP_LOGIN="IP Login" +KEYBOARD_SHORTCUTS="Keyboard Shortcuts" +MODALS="Modals" +MODULES_ANYWHERE="Modules Anywhere" +QUICK_INDEX="Quick Index" +REREPLACER="ReReplacer" +SIMPLE_USER_NOTES="Simple User Notes" +SLIDERS="Sliders" +SNIPPETS="Snippets" +SOURCERER="Sourcerer" +TABS="Tabs" +TOOLTIPS="Tooltips" +WHAT_NOTHING="What? Nothing!" diff --git a/deployed/regularlabs/plugins/system/regularlabs/language/en-GB/en-GB.plg_system_regularlabs.sys.ini b/deployed/regularlabs/plugins/system/regularlabs/language/en-GB/en-GB.plg_system_regularlabs.sys.ini new file mode 100644 index 00000000..fdf6b693 --- /dev/null +++ b/deployed/regularlabs/plugins/system/regularlabs/language/en-GB/en-GB.plg_system_regularlabs.sys.ini @@ -0,0 +1,13 @@ +;; @package Regular Labs Library +;; @version 18.12.3953 +;; +;; @author Peter van Westen +;; @link http://www.regularlabs.com +;; @copyright Copyright © 2018 Regular Labs All Rights Reserved +;; @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL +;; +;; @translate Want to help with translations? See: https://www.regularlabs.com/translate + +PLG_SYSTEM_REGULARLABS="System - Regular Labs Library" +PLG_SYSTEM_REGULARLABS_DESC="Regular Labs Library - used by Regular Labs extensions" +REGULAR_LABS_LIBRARY="Regular Labs Library" diff --git a/deployed/regularlabs/plugins/system/regularlabs/language/hu-HU/hu-HU.plg_system_regularlabs.ini b/deployed/regularlabs/plugins/system/regularlabs/language/hu-HU/hu-HU.plg_system_regularlabs.ini new file mode 100644 index 00000000..e6aaa416 --- /dev/null +++ b/deployed/regularlabs/plugins/system/regularlabs/language/hu-HU/hu-HU.plg_system_regularlabs.ini @@ -0,0 +1,474 @@ +;; @package Regular Labs Library +;; @version 18.12.3953 +;; +;; @author Peter van Westen +;; @link http://www.regularlabs.com +;; @copyright Copyright © 2018 Regular Labs All Rights Reserved +;; @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL +;; +;; @translate Want to help with translations? See: https://www.regularlabs.com/translate + +PLG_SYSTEM_REGULARLABS="Rendszer - Regular Labs Library" +PLG_SYSTEM_REGULARLABS_DESC="Regular Labs Library - a Regular Labs bővítményekhez szükséges" +REGULAR_LABS_LIBRARY="Regular Labs Library" + +; REGULAR_LABS_LIBRARY_DESC="[[%1:warning%]]The Regular Labs extensions need this plugin and will not function without it.

Regular Labs extensions include:[[%2:extensions%]]" +; REGULAR_LABS_LIBRARY_DESC_WARNING="Do not uninstall or disable this plugin if you are using any Regular Labs extensions." + +; COM_CONFIG_RL_ACTIONLOG_FIELDSET_LABEL="User Actions Log" +COM_MODULES_DESCRIPTION_FIELDSET_LABEL="Leírás" +COM_PLUGINS_DESCRIPTION_FIELDSET_LABEL="Leírás" +COM_PLUGINS_RL_BEHAVIOUR_FIELDSET_LABEL="Viselkedés" +; COM_PLUGINS_RL_DEFAULT_SETTINGS_FIELDSET_LABEL="Default Settings" +COM_PLUGINS_RL_MEDIA_FIELDSET_LABEL="Média" +; COM_PLUGINS_RL_SETTINGS_ADMIN_MODULE_FIELDSET_LABEL="Administrator Module Options" +; COM_PLUGINS_RL_SETTINGS_EDITOR_BUTTON_FIELDSET_LABEL="Editor Button Options" +; COM_PLUGINS_RL_SETTINGS_SECURITY_FIELDSET_LABEL="Security Options" +COM_PLUGINS_RL_SETUP_FIELDSET_LABEL="Beállítás" +; COM_PLUGINS_RL_STYLING_FIELDSET_LABEL="Styling" +; COM_PLUGINS_RL_TAG_SYNTAX_FIELDSET_LABEL="Tag Syntax" + +; RL_ACCESS_LEVELS="Access Levels" +; RL_ACCESS_LEVELS_DESC="Select the access levels to assign to." +; RL_ACTION_CHANGE_DEFAULT="Change Default" +; RL_ACTION_CHANGE_STATE="Change Publish State" +; RL_ACTION_CREATE="Create" +; RL_ACTION_DELETE="Delete" +RL_ACTION_INSTALL="Telepítés" +RL_ACTION_UNINSTALL="Eltávolítás" +RL_ACTION_UPDATE="Frissítés" +; RL_ACTIONLOG_EVENTS="Events To Log" +; RL_ACTIONLOG_EVENTS_DESC="Select the actions to include in the User Actions Log." +; RL_ADMIN="Admin" +RL_ADVANCED="Haladó" +RL_AKEEBASUBS="Akeeba Subscriptions" +RL_ALL="ÖSSZES" +; RL_ALL_DESC="Will be published if ALL of below assignments are matched." +RL_ALL_RIGHTS_RESERVED="Minden jog fenntartva" +; RL_ALSO_ON_CHILD_ITEMS="Also on child items" +; RL_ALSO_ON_CHILD_ITEMS_DESC="Also assign to child items of the selected items?" +; RL_ALSO_ON_CHILD_ITEMS_MENUITEMS_DESC="The child items refer to actual sub-items in the above selection. They do not refer to links on selected pages." +RL_ANY="BÁRMELY" +; RL_ANY_DESC="Will be published if ANY (one or more) of below assignments are matched.
Assignment groups where 'Ignore' is selected will be ignored." +RL_ARE_YOU_SURE="Biztos vagy benne?" +RL_ARTICLE="Cikk" +RL_ARTICLE_AUTHORS="Szerzők" +; RL_ARTICLE_AUTHORS_DESC="Select the authors to assign to." +RL_ARTICLES="Cikkek" +; RL_ARTICLES_DESC="Select the articles to assign to." +; RL_AS_EXPORTED="As exported" +; RL_ASSIGNMENTS="Assignments" +; RL_ASSIGNMENTS_DESC="By selecting the specific assignments you can limit where this %s should or shouldn't be published.
To have it published on all pages, simply do not specify any assignments." +RL_AUSTRALIA="Ausztrália" +RL_AUTHORS="Szerzők" +RL_AUTO="Automatikus" +RL_BEHAVIOR="Viselkedés" +RL_BEHAVIOUR="Viselkedés" +RL_BOOTSTRAP="Bootstrap" +; RL_BOOTSTRAP_FRAMEWORK_DISABLED="You have disabled the Bootstrap Framework to be initiated. %s needs the Bootstrap Framework to function. Make sure your template or other extensions load the necessary scripts to replace the required functionality." +RL_BOTH="Mindkettő" +RL_BOTTOM="Alulra" +RL_BROWSERS="Böngészők" +; RL_BROWSERS_DESC="Select the browsers to assign to. Keep in mind that browser detection is not always 100% accurate. Users can setup their browser to mimic other browsers" +; RL_BUTTON_ICON="Button Icon" +; RL_BUTTON_ICON_DESC="Select which icon to show in the button." +RL_BUTTON_TEXT="Gomb szöveg" +; RL_BUTTON_TEXT_DESC="This text will be shown in the Editor Button." +; RL_CACHE_TIME="Cache Time" +; RL_CACHE_TIME_DESC="The maximum length of time in minutes for a cache file to be stored before it is refreshed. Leave empty to use the global setting." +RL_CATEGORIES="Kategóriák" +; RL_CATEGORIES_DESC="Select the categories to assign to." +RL_CHANGELOG="Változások listája" +RL_CLASSNAME="CSS osztály" +; RL_COLLAPSE="Collapse" +RL_COM="Komponens" +; RL_COMBINE_ADMIN_MENU="Combine Admin Menu" +; RL_COMBINE_ADMIN_MENU_DESC="Select to combine all Regular Labs - components into a submenu in the administrator menu." +RL_COMPONENTS="Komponensek" +; RL_COMPONENTS_DESC="Select the components to assign to." +RL_CONTENT="Tartalom" +; RL_CONTENT_KEYWORDS="Content Keywords" +; RL_CONTENT_KEYWORDS_DESC="Enter the keywords found in the content to assign to. Use commas to separate the keywords." +; RL_CONTINENTS="Continents" +; RL_CONTINENTS_DESC="Select the continents to assign to." +; RL_COOKIECONFIRM="Cookie Confirm" +; RL_COOKIECONFIRM_COOKIES="Cookies allowed" +; RL_COOKIECONFIRM_COOKIES_DESC="Assign to whether cookies are allowed or disallowed, based on the configuration of Cookie Confirm (by Twentronix) and the visitor's choice to accept or decline cookies." +RL_COPY_OF="%s másolata" +RL_COPYRIGHT="Copyright" +RL_COUNTRIES="országok" +; RL_COUNTRIES_DESC="Select the countries to assign to." +; RL_CSS_CLASS="Class (CSS)" +; RL_CSS_CLASS_DESC="Define a css class name for styling purposes." +RL_CURRENT="Jelenlegi" +; RL_CURRENT_DATE="Current date/time: %s" +RL_CURRENT_VERSION="A jelenlegi verziód %s" +; RL_CUSTOM_CODE="Custom Code" +; RL_CUSTOM_CODE_DESC="Enter the code the Editor Button should insert into the content (instead of the default code)." +; RL_CUSTOM_FIELD="Custom Field" +RL_CUSTOM_FIELDS="Egyéni mezők" +RL_DATE="Dátum" +; RL_DATE_RECURRING="Recurring" +; RL_DATE_RECURRING_DESC="Select to apply date range every year. (So the year in the selection will be ignored)" +RL_DATE_TIME="Dátum & idő" +; RL_DATE_TIME_DESC="The date and time assignments use the date/time of your servers, not that of the visitors system." +RL_DAYS="A hét napjai" +; RL_DAYS_DESC="Select days of the week to assign to." +; RL_DEFAULT_ORDERING="Default Ordering" +; RL_DEFAULT_ORDERING_DESC="Set the default ordering of the list items" +; RL_DEFAULT_SETTINGS="Default Settings" +; RL_DEFAULTS="Defaults" +; RL_DEVICE_DESKTOP="Desktop" +RL_DEVICE_MOBILE="Mobil" +; RL_DEVICE_TABLET="Tablet" +; RL_DEVICES="Devices" +; RL_DEVICES_DESC="Select the devices to assign to. Keep in mind that device detection is not always 100% accurate. Users can setup their device to mimic other devices" +RL_DIRECTION="Irány" +; RL_DIRECTION_DESC="Select the direction" +; RL_DISABLE_ON_ADMIN_COMPONENTS_DESC="Select in which administrator components NOT to enable the use of this extension." +; RL_DISABLE_ON_ALL_COMPONENTS_DESC="Select in which components NOT to enable the use of this extension." +RL_DISABLE_ON_COMPONENTS="Letiltása a komponensekben" +; RL_DISABLE_ON_COMPONENTS_DESC="Select in which frontend components NOT to enable the use of this extension." +; RL_DISPLAY_EDITOR_BUTTON="Display Editor Button" +; RL_DISPLAY_EDITOR_BUTTON_DESC="Select to display an editor button." +RL_DISPLAY_LINK="Megjelenített hivatkozás" +; RL_DISPLAY_LINK_DESC="How do you want the link to be displayed?" +; RL_DISPLAY_TOOLBAR_BUTTON="Display Toolbar Button" +; RL_DISPLAY_TOOLBAR_BUTTON_DESC="Select to show a button in the toolbar." +; RL_DISPLAY_TOOLTIP="Display Tooltip" +; RL_DISPLAY_TOOLTIP_DESC="Select to display a tooltip with extra info when mouse hovers over link/icon." +RL_EASYBLOG="EasyBlog" +RL_ENABLE="Engedélyez" +; RL_ENABLE_ACTIONLOG="Log User Actions" +; RL_ENABLE_ACTIONLOG_DESC="Select to store User Actions. These actions will be visible in the User Actions Log module." +; RL_ENABLE_IN="Enable in" +; RL_ENABLE_IN_ADMIN="Enable in administrator" +; RL_ENABLE_IN_ADMIN_DESC="If enabled, the plugin will also work in the administrator side of the website.

Normally you will not need this. And it can cause unwanted effects, like slowing down the administrator and the plugin tags being handled in areas you don't want it." +; RL_ENABLE_IN_ARTICLES="Enable in articles" +; RL_ENABLE_IN_COMPONENTS="Enable in components" +; RL_ENABLE_IN_DESC="Select whether to enable in the frontend or administrator side or both." +; RL_ENABLE_IN_FRONTEND="Enable in frontend" +; RL_ENABLE_IN_FRONTEND_DESC="If enabled, it will also be available in the frontend." +; RL_ENABLE_OTHER_AREAS="Enable other areas" +RL_EXCLUDE="Kizárt" +RL_EXPAND="Bontás" +RL_EXPORT="Export" +; RL_EXPORT_FORMAT="Export Format" +; RL_EXPORT_FORMAT_DESC="Select the file format for the export files." +; RL_EXTRA_PARAMETERS="Extra Parameters" +; RL_EXTRA_PARAMETERS_DESC="Enter any extra parameters that cannot be set with the available settings" +; RL_FALL="Fall / Autumn" +; RL_FEATURES="Features" +RL_FIELD_NAME="Mező név" +RL_FIELD_PARAM_MULTIPLE="Többszörös" +; RL_FIELD_PARAM_MULTIPLE_DESC="Allow multiple values to be selected." +; RL_FIELD_VALUE="Field Value" +; RL_FILES_NOT_FOUND="Required %s files not found!" +RL_FILTERS="Szűrők" +RL_FINISH_PUBLISHING="Közzététel vége" +; RL_FINISH_PUBLISHING_DESC="Enter the date to end publishing" +; RL_FIX_HTML="Fix HTML" +; RL_FIX_HTML_DESC="Select to let the extension fix any html structure issues it finds. This is often necessary to deal with surrounding html tags.

Only switch this off if you have issues with this." +RL_FLEXICONTENT="FLEXIcontent" +; RL_FOR_MORE_GO_PRO="For more functionality you can purchase the PRO version." +RL_FORM2CONTENT="Form2Content" +; RL_FRAMEWORK_NO_LONGER_USED="The Old NoNumber Framework does not seem to be used by any other extensions you have installed. It is probably safe to disable or uninstall this plugin." +RL_FRONTEND="Kiszolgáló" +RL_GALLERY="Gallery" +; RL_GEO="Geolocating" +; RL_GEO_DESC="Geolocating is not always 100% accurate. The geolocation is based on the IP address of the visitor. Not all IP addresses are fixed or known." +; RL_GEO_GEOIP_COPYRIGHT_DESC="This product includes GeoLite2 data created by MaxMind, available from [[%1:link%]]" +; RL_GEO_NO_GEOIP_LIBRARY="The Regular Labs GeoIP library is not installed. You need to [[%1:link start%]]install the Regular Labs GeoIP library[[%2:link end%]] to be able to use the Geolocating assignments." +RL_GO_PRO="Pro verzióra frissítés!" +; RL_HEADING_1="Heading 1" +; RL_HEADING_2="Heading 2" +; RL_HEADING_3="Heading 3" +; RL_HEADING_4="Heading 4" +; RL_HEADING_5="Heading 5" +; RL_HEADING_6="Heading 6" +; RL_HEADING_ACCESS_ASC="Access ascending" +; RL_HEADING_ACCESS_DESC="Access descending" +; RL_HEADING_CATEGORY_ASC="Category ascending" +; RL_HEADING_CATEGORY_DESC="Category descending" +; RL_HEADING_CLIENTID_ASC="Location ascending" +; RL_HEADING_CLIENTID_DESC="Location descending" +; RL_HEADING_COLOR_ASC="Colour ascending" +; RL_HEADING_COLOR_DESC="Colour descending" +; RL_HEADING_DEFAULT_ASC="Default ascending" +; RL_HEADING_DEFAULT_DESC="Default descending" +; RL_HEADING_DESCRIPTION_ASC="Description ascending" +; RL_HEADING_DESCRIPTION_DESC="Description descending" +; RL_HEADING_ID_ASC="ID ascending" +; RL_HEADING_ID_DESC="ID descending" +; RL_HEADING_LANGUAGE_ASC="Language ascending" +; RL_HEADING_LANGUAGE_DESC="Language descending" +; RL_HEADING_ORDERING_ASC="Ordering ascending" +; RL_HEADING_ORDERING_DESC="Ordering descending" +; RL_HEADING_PAGES_ASC="Menu Items ascending" +; RL_HEADING_PAGES_DESC="Menu Items descending" +; RL_HEADING_POSITION_ASC="Position ascending" +; RL_HEADING_POSITION_DESC="Position descending" +RL_HEADING_STATUS_ASC="Státusz növekvő" +RL_HEADING_STATUS_DESC="Státusz csökkenő" +; RL_HEADING_STYLE_ASC="Style ascending" +; RL_HEADING_STYLE_DESC="Style descending" +; RL_HEADING_TEMPLATE_ASC="Template ascending" +; RL_HEADING_TEMPLATE_DESC="Template descending" +RL_HEADING_TITLE_ASC="Cím szerint növekvő" +RL_HEADING_TITLE_DESC="Cím szerint csökkenő" +; RL_HEADING_TYPE_ASC="Type ascending" +; RL_HEADING_TYPE_DESC="Type descending" +RL_HEIGHT="Magasság" +; RL_HEMISPHERE="Hemisphere" +; RL_HEMISPHERE_DESC="Select the hemisphere your website is located in" +RL_HIGH="Nagy" +RL_HIKASHOP="HikaShop" +; RL_HOME_PAGE="Home Page" +; RL_HOME_PAGE_DESC="Unlike selecting the home page (default) item via the Menu Items, this will only match the real home page, not any URL that has the same Itemid as the home menu item.

This might not work for all 3rd party SEF extensions." +RL_HTML_LINK="[[%1:text%]]" +; RL_ICON_ONLY="Icon only" +; RL_IGNORE="Ignore" +RL_IMAGE="Kép" +; RL_IMAGE_ALT="Image Alt" +; RL_IMAGE_ALT_DESC="The Alt value of the image." +; RL_IMAGE_ATTRIBUTES="Image Attributes" +; RL_IMAGE_ATTRIBUTES_DESC="The extra attributes of the image, like: alt="My image" width="300"" +RL_IMPORT="Importálás" +RL_IMPORT_ITEMS="Elemek importálása" +RL_INCLUDE="Belefoglalt" +; RL_INCLUDE_CHILD_ITEMS="Include child items" +; RL_INCLUDE_CHILD_ITEMS_DESC="Also include child items of the selected items?" +RL_INCLUDE_NO_ITEMID="Ne legyen benne az elem azonosító" +; RL_INCLUDE_NO_ITEMID_DESC="Also assign when no menu Itemid is set in URL?" +; RL_INITIALISE_EVENT="Initialise on Event" +; RL_INITIALISE_EVENT_DESC="Set the internal Joomla event on which the plugin should be initialised. Only change this if you experience issues with the plugin not working." +; RL_INSERT="Insert" +; RL_INSERT_DATE_NAME="Insert Date / Name" +; RL_IP_RANGES="IP Addresses / Ranges" +; RL_IP_RANGES_DESC="A comma and/or enter separated list of IP addresses and IP ranges. For instance:
127.0.0.1
128.0-128.1
129" +; RL_IPS="IP Addresses" +; RL_IS_FREE_VERSION="This is the FREE version of %s." +RL_ITEM="Elem" +RL_ITEM_IDS="Elem AZ" +; RL_ITEM_IDS_DESC="Enter the item ids to assign to. Use commas to separate the ids." +RL_ITEMS="Elemek" +; RL_ITEMS_DESC="Select the items to assign to." +; RL_JCONTENT="Joomla! Content" +; RL_JED_REVIEW="Like this extension? [[%1:start link%]]Leave a review at the JED[[%2:end link%]]" +; RL_JOOMLA2_VERSION_ON_JOOMLA3="You are running a Joomla 2.5 version of %1$s on Joomla 3. Please reinstall %1$s to fix the problem." +; RL_JQUERY_DISABLED="You have disabled the jQuery script. %s needs jQuery to function. Make sure your template or other extensions load the necessary scripts to replace the required functionality." +RL_K2="K2" +RL_K2_CATEGORIES="K2 kategóriák" +RL_LANGUAGE="Nyelv" +; RL_LANGUAGE_DESC="Select the language to assign to." +RL_LANGUAGES="Nyelvek" +; RL_LANGUAGES_DESC="Select the languages to assign to." +RL_LAYOUT="Elrendezás" +; RL_LAYOUT_DESC="Select the layout to use. You can override this layout in the component or template." +; RL_LEVELS="Levels" +; RL_LEVELS_DESC="Select the levels to assign to." +; RL_LIB="Library" +RL_LINK_TEXT="Hivatkozás szöveg" +; RL_LINK_TEXT_DESC="The text to display as link." +RL_LIST="Lista" +; RL_LOAD_BOOTSTRAP_FRAMEWORK="Load Bootstrap Framework" +; RL_LOAD_BOOTSTRAP_FRAMEWORK_DESC="Disable to not initiate the Bootstrap Framework." +; RL_LOAD_JQUERY="Load jQuery Script" +; RL_LOAD_JQUERY_DESC="Select to load the core jQuery script. You can disable this if you experience conflicts if your template or other extensions load their own version of jQuery." +; RL_LOAD_MOOTOOLS="Load Core MooTools" +; RL_LOAD_MOOTOOLS_DESC="Select to load the core MooTools script. You can disable this if you experience conflicts if your template or other extensions load their own version of MooTools." +; RL_LOAD_STYLESHEET="Load Stylesheet" +; RL_LOAD_STYLESHEET_DESC="Select to load the extensions stylesheet. You can disable this if you place all your own styles in some other stylesheet, like the templates stylesheet." +RL_LOW="Alacsony" +RL_LTR="Balról jobbra" +; RL_MATCH_ALL="Match All" +; RL_MATCH_ALL_DESC="Select to only let the assignment pass if all of the selected items are matched." +; RL_MATCHING_METHOD="Matching Method" +; RL_MATCHING_METHOD_DESC="Should all or any assignments be matched?

[[%1:all%]]
[[%2:all description%]]

[[%3:any%]]
[[%4:any description%]]" +; RL_MAX_LIST_COUNT="Maximum List Count" +; RL_MAX_LIST_COUNT_DESC="The maximum number of elements to show in the multi-select lists. If the total number of items is higher, the selection field will be displayed as a text field.

You can set this number lower if you experience long pageloads due to high number of items in lists." +; RL_MAX_LIST_COUNT_INCREASE="Increase Maximum List Count" +; RL_MAX_LIST_COUNT_INCREASE_DESC="There are more than [[%1:max%]] items.

To prevent slow pages this field is displayed as a textarea instead of a dynamic select list.

You can increase the '[[%2:max setting%]]' in the Regular Labs Library plugin settings." +; RL_MAXIMIZE="Maximize" +; RL_MEDIA_VERSIONING="Use Media Versioning" +; RL_MEDIA_VERSIONING_DESC="Select to add the extension version number to the end of media (js/css) urls, to make browsers force load the correct file." +RL_MEDIUM="Közepes" +RL_MENU_ITEMS="Menü elemek" +; RL_MENU_ITEMS_DESC="Select the menu items to assign to." +RL_META_KEYWORDS="Meta kulcsszavak" +; RL_META_KEYWORDS_DESC="Enter the keywords found in the meta keywords to assign to. Use commas to separate the keywords." +RL_MIJOSHOP="MijoShop" +RL_MINIMIZE="Minimalizál" +; RL_MOBILE_BROWSERS="Mobile Browsers" +RL_MOD="Modul" +RL_MONTHS="Hónap" +; RL_MONTHS_DESC="Select months to assign to." +; RL_MORE_INFO="More info" +; RL_N_ITEMS_ARCHIVED="%s items archived." +; RL_N_ITEMS_ARCHIVED_1="%s item archived." +; RL_N_ITEMS_CHECKED_IN_0="No items checked in." +; RL_N_ITEMS_CHECKED_IN_1="%d item checked in." +; RL_N_ITEMS_CHECKED_IN_MORE="%d items checked in." +; RL_N_ITEMS_DELETED="%s items deleted." +; RL_N_ITEMS_DELETED_1="%s item deleted." +; RL_N_ITEMS_FEATURED="%s items featured." +; RL_N_ITEMS_FEATURED_1="%s item featured." +; RL_N_ITEMS_PUBLISHED="%s items published." +; RL_N_ITEMS_PUBLISHED_1="%s item published." +; RL_N_ITEMS_TRASHED="%s items trashed." +; RL_N_ITEMS_TRASHED_1="%s item trashed." +; RL_N_ITEMS_UNFEATURED="%s items unfeatured." +; RL_N_ITEMS_UNFEATURED_1="%s item unfeatured." +; RL_N_ITEMS_UNPUBLISHED="%s items unpublished." +; RL_N_ITEMS_UNPUBLISHED_1="%s item unpublished." +; RL_N_ITEMS_UPDATED="%d items updated." +; RL_N_ITEMS_UPDATED_1="One item has been updated" +; RL_NEW_CATEGORY="Create New Category" +; RL_NEW_CATEGORY_ENTER="Enter a new category name" +RL_NEW_VERSION_AVAILABLE="Új verzió érhető el" +; RL_NEW_VERSION_OF_AVAILABLE="A new version of %s is available" +; RL_NO_ICON="No icon" +; RL_NO_ITEMS_FOUND="No items found." +RL_NORMAL="Normál" +RL_NORTHERN="Északi" +RL_NOT="Nem" +RL_ONLY="Csak" +; RL_ONLY_AVAILABLE_IN_JOOMLA="Only available in Joomla %s or higher." +RL_ONLY_AVAILABLE_IN_PRO="Ez csak a PRO verzióban érhető el!" +; RL_ONLY_AVAILABLE_IN_PRO_LIST_OPTION="(Only available in PRO version)" +; RL_ONLY_VISIBLE_TO_ADMIN="This message will only be displayed to (Super) Administrators." +; RL_OPTION_SELECT="- Select -" +; RL_OPTION_SELECT_CLIENT="- Select Client -" +; RL_OS="Operating Systems" +; RL_OS_DESC="Select the operating systems to assign to. Keep in mind that operating system detection is not always 100% accurate. Users can setup their browser to mimic other operating systems." +RL_OTHER_AREAS="Egyéb területek" +RL_OTHER_OPTIONS="Egyéb beállítások" +RL_OTHER_SETTINGS="Egyéb beállítások" +RL_OTHERS="Egyebek" +RL_PAGE_TYPES="Oldal típusok" +; RL_PAGE_TYPES_DESC="Select on what page types the assignment should be active." +; RL_PHP="Custom PHP" +; RL_PHP_DESC="Enter a piece of PHP code to evaluate. The code must return the value true or false.

For instance:

[[%1:code%]]" +; RL_PLACE_HTML_COMMENTS="Place HTML comments" +; RL_PLACE_HTML_COMMENTS_DESC="By default HTML comments are placed around the output of this extension.

These comments can help you troubleshoot when you don't get the output you expect.

If you prefer to not have these comments in your HTML output, turn this option off." +; RL_PLG_ACTIONLOG="Action Log Plugin" +; RL_PLG_EDITORS-XTD="Editor Button Plugin" +; RL_PLG_FIELDS="Field Plugin" +; RL_PLG_SYSTEM="System Plugin" +; RL_POSTALCODES="Postal Codes" +; RL_POSTALCODES_DESC="A comma separated list of postal codes (12345) or postal code ranges (12300-12500).
This can only be used for [[%1:start link%]]a limited number of countries and IP addresses[[%2:end link%]]." +; RL_POWERED_BY="Powered by %s" +RL_PRODUCTS="Termékek" +; RL_PUBLISHED_DESC="You can use this to (temporarily) disable this item." +; RL_PUBLISHING_ASSIGNMENTS="Publishing Assignments" +; RL_PUBLISHING_SETTINGS="Publish items" +RL_RANDOM="Véletlenszerű" +RL_REDSHOP="RedShop" +; RL_REGIONS="Regions / States" +; RL_REGIONS_DESC="Select the regions / states to assign to." +; RL_REGULAR_EXPRESSIONS="Use Regular Expressions" +; RL_REGULAR_EXPRESSIONS_DESC="Select to treat the value as regular expressions." +; RL_REMOVE_IN_DISABLED_COMPONENTS="Remove in Disabled Components" +; RL_REMOVE_IN_DISABLED_COMPONENTS_DESC="If selected, the plugin syntax will get removed from the component. If not, the original plugins syntax will remain intact." +; RL_RESIZE_IMAGES="Resize Images" +; RL_RESIZE_IMAGES_CROP="Crop" +; RL_RESIZE_IMAGES_CROP_DESC="Select to make the resized image crop the original image.
If selected, the resized image will always have the set width and height.
If not selected, the resized image will be resized to the maximum width or height maintaining its aspect ratio." +; RL_RESIZE_IMAGES_DESC="If selected, resized images will be automatically created for images if they do not exist yet. The resized images will be created using below settings." +; RL_RESIZE_IMAGES_FILETYPES="Only on Filetypes" +; RL_RESIZE_IMAGES_FILETYPES_DESC="Select the filetypes to do resizing on." +RL_RESIZE_IMAGES_FOLDER="Mappa" +; RL_RESIZE_IMAGES_FOLDER_DESC="The folder containing the resized images. This will be a subfolder of the folder containing your original images." +; RL_RESIZE_IMAGES_HEIGHT_DESC="Set the height of the resized image in pixels (ie 180)." +; RL_RESIZE_IMAGES_NO_HEIGHT_DESC="The Height will be calculated based on the Width defined above and the aspect ratio of the original image." +; RL_RESIZE_IMAGES_NO_WIDTH_DESC="The Width will be calculated based on the Height defined below and the aspect ratio of the original image." +; RL_RESIZE_IMAGES_QUALITY="JPG Quality" +; RL_RESIZE_IMAGES_QUALITY_DESC="The quality of the resized images. Choose from Low, Medium or High. The higher the quality, the larger the resulting files.
This only affects jpeg images." +; RL_RESIZE_IMAGES_USE_WIDTH_OR_HEIGHT="Set" +; RL_RESIZE_IMAGES_USE_WIDTH_OR_HEIGHT_DESC="Select whether to resize images using the maximum width or height." +; RL_RESIZE_IMAGES_WIDTH_DESC="Set the width of the resized image in pixels (ie 320)." +; RL_RTL="Right-to-Left" +; RL_SAVE_CONFIG="After saving the Options it will not pop up on page load anymore." +RL_SEASONS="Évadok" +; RL_SEASONS_DESC="Select seasons to assign to." +RL_SELECT="Kijelölés" +; RL_SELECT_A_CATEGORY="Select a Category" +RL_SELECT_ALL="Összes kijelölése" +RL_SELECT_AN_ARTICLE="Válasszon cikket" +; RL_SELECTED="Selected" +RL_SELECTION="Választás" +; RL_SELECTION_DESC="Select whether to include or exclude the selection for the assignment.

Include
Publish only on selection.

Exclude
Publish everywhere except on selection." +; RL_SETTINGS_ADMIN_MODULE="Administrator Module Options" +; RL_SETTINGS_EDITOR_BUTTON="Editor Button Options" +; RL_SETTINGS_SECURITY="Security Options" +; RL_SHOW_ASSIGNMENTS="Show Assignments" +; RL_SHOW_ASSIGNMENTS_DESC="Select whether to only show the selected assignments. You can use this to get a clean overview of the active assignments." +; RL_SHOW_ASSIGNMENTS_SELECTED_DESC="All not-selected assignment types are now hidden from view." +; RL_SHOW_COPYRIGHT="Show Copyright" +; RL_SHOW_COPYRIGHT_DESC="If selected, extra copyright info will be displayed in the admin views. Regular Labs extensions never show copyright info or backlinks on the frontend." +; RL_SHOW_HELP_MENU="Show Help Menu Item" +; RL_SHOW_HELP_MENU_DESC="Select to show a link to the Regular Labs website in the Administrator Help menu." +; RL_SHOW_ICON="Show Button Icon" +; RL_SHOW_ICON_DESC="If selected, the icon will be displayed in the Editor Button." +; RL_SHOW_UPDATE_NOTIFICATION="Show Update Notification" +; RL_SHOW_UPDATE_NOTIFICATION_DESC="If selected, an update notification will be shown in the main component view when there is a new version for this extension." +RL_SIMPLE="Egyszerű" +; RL_SLIDES="Slides" +RL_SOUTHERN="Déli" +RL_SPRING="Tavasz" +RL_START="Start" +RL_START_PUBLISHING="Közzététel kezdete" +; RL_START_PUBLISHING_DESC="Enter the date to start publishing" +; RL_STRIP_SURROUNDING_TAGS="Strip Surrounding Tags" +; RL_STRIP_SURROUNDING_TAGS_DESC="Select to always remove html tags (div, p, span) surrounding the plugin tag. If switched off, the plugin will try to remove tags that break the html structure (like p inside p tags)." +; RL_STYLING="Styling" +RL_SUMMER="Nyár" +; RL_TABLE_NOT_FOUND="Required %s database table not found!" +; RL_TABS="Tabs" +; RL_TAG_CHARACTERS="Tag Characters" +; RL_TAG_CHARACTERS_DESC="The surrounding characters of the tag syntax.

Note: If you change this, all existing tags will not work anymore." +; RL_TAG_SYNTAX="Tag Syntax" +; RL_TAG_SYNTAX_DESC="The word to be used in the tags.

Note: If you change this, all existing tags will not work anymore." +RL_TAGS="Címkék" +; RL_TAGS_DESC="Enter the tags to assign to. Use commas to separate the tags." +RL_TEMPLATES="Sablonok" +; RL_TEMPLATES_DESC="Select the templates to assign to." +RL_TEXT="Szöveg" +; RL_TEXT_HTML="Text (HTML)" +RL_TEXT_ONLY="Csak szöveg" +; RL_THIS_EXTENSION_NEEDS_THE_MAIN_EXTENSION_TO_FUNCTION="This extension needs %s to function correctly!" +RL_TIME="Idő" +; RL_TIME_FINISH_PUBLISHING_DESC="Enter the time to end publishing.

Format: 23:59" +; RL_TIME_START_PUBLISHING_DESC="Enter the time to start publishing.

Format: 23:59" +RL_TOGGLE="Átkapcsolás" +RL_TOOLTIP="Súgóbuborék" +RL_TOP="Felülre" +RL_TOTAL="Összesen" +RL_TYPES="típusok" +; RL_TYPES_DESC="Select the types to assign to." +; RL_UNSELECT_ALL="Unselect All" +RL_UNSELECTED="Nincs kiválasztva" +RL_UPDATE_TO="%s verzióra frissítés" +RL_URL="URL" +RL_URL_PARTS="URL egyezések" +; RL_URL_PARTS_DESC="Enter (part of) the URLs to match.
Use a new line for each different match." +; RL_URL_PARTS_REGEX="Url parts will be matched using regular expressions. So make sure the string uses valid regex syntax." +; RL_USE_CONTENT_ASSIGNMENTS="For category & article (item) assignments, see the above Joomla! Content section." +; RL_USE_CUSTOM_CODE="Use Custom Code" +; RL_USE_CUSTOM_CODE_DESC="If selected, the Editor Button will insert the given custom code instead." +; RL_USE_SIMPLE_BUTTON="Use Simple Button" +; RL_USE_SIMPLE_BUTTON_DESC="Select to use a simple insert button, that simply inserts some example syntax into the editor." +; RL_USER_GROUP_LEVELS="User Group Levels" +RL_USER_GROUPS="Felhasználói csoportok" +; RL_USER_GROUPS_DESC="Select the user groups to assign to." +RL_USER_IDS="Felhasználói AZ" +; RL_USER_IDS_DESC="Enter the user ids to assign to. Use commas to separate ids." +RL_USERS="Felhasználók" +RL_UTF8="UTF-8" +RL_VIDEO="Videó" +RL_VIEW="Nézet" +; RL_VIEW_DESC="Select what default view should be used when creating a new item." +RL_VIRTUEMART="VirtueMart" +RL_WIDTH="Szélesség" +RL_WINTER="Tél" +RL_ZOO="ZOO" +; RL_ZOO_CATEGORIES="ZOO Categories" diff --git a/deployed/regularlabs/plugins/system/regularlabs/language/hu-HU/hu-HU.plg_system_regularlabs.sys.ini b/deployed/regularlabs/plugins/system/regularlabs/language/hu-HU/hu-HU.plg_system_regularlabs.sys.ini new file mode 100644 index 00000000..455ed10c --- /dev/null +++ b/deployed/regularlabs/plugins/system/regularlabs/language/hu-HU/hu-HU.plg_system_regularlabs.sys.ini @@ -0,0 +1,13 @@ +;; @package Regular Labs Library +;; @version 18.12.3953 +;; +;; @author Peter van Westen +;; @link http://www.regularlabs.com +;; @copyright Copyright © 2018 Regular Labs All Rights Reserved +;; @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL +;; +;; @translate Want to help with translations? See: https://www.regularlabs.com/translate + +PLG_SYSTEM_REGULARLABS="Rendszer - Regular Labs Library" +PLG_SYSTEM_REGULARLABS_DESC="Regular Labs Library - a Regular Labs bővítményekhez szükséges" +REGULAR_LABS_LIBRARY="Regular Labs Library" diff --git a/deployed/regularlabs/plugins/system/regularlabs/regularlabs.php b/deployed/regularlabs/plugins/system/regularlabs/regularlabs.php new file mode 100644 index 00000000..e161d06f --- /dev/null +++ b/deployed/regularlabs/plugins/system/regularlabs/regularlabs.php @@ -0,0 +1,197 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; +use Joomla\CMS\Plugin\CMSPlugin as JPlugin; +use Joomla\CMS\Uri\Uri as JUri; +use Joomla\Registry\Registry; +use RegularLabs\Library\Document as RL_Document; +use RegularLabs\Library\Parameters as RL_Parameters; +use RegularLabs\Library\Uri as RL_Uri; +use RegularLabs\Plugin\System\RegularLabs\AdminMenu as RL_AdminMenu; +use RegularLabs\Plugin\System\RegularLabs\DownloadKey as RL_DownloadKey; +use RegularLabs\Plugin\System\RegularLabs\QuickPage as RL_QuickPage; +use RegularLabs\Plugin\System\RegularLabs\SearchHelper as RL_SearchHelper; + +if ( ! is_file(__DIR__ . '/vendor/autoload.php')) +{ + return; +} + +require_once __DIR__ . '/vendor/autoload.php'; + +if (is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) +{ + require_once JPATH_LIBRARIES . '/regularlabs/autoload.php'; +} + +JFactory::getLanguage()->load('plg_system_regularlabs', __DIR__); + +class PlgSystemRegularLabs extends JPlugin +{ + public function onAfterRoute() + { + if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) + { + if (JFactory::getApplication()->isClient('administrator')) + { + JFactory::getApplication()->enqueueMessage('The Regular Labs Library folder is missing or incomplete: ' . JPATH_LIBRARIES . '/regularlabs', 'error'); + } + + return; + } + + RL_DownloadKey::update(); + + RL_SearchHelper::load(); + + RL_QuickPage::render(); + } + + public function onAfterDispatch() + { + if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) + { + return; + } + + if ( ! RL_Document::isAdmin(true) || ! RL_Document::isHtml() + ) + { + return; + } + + RL_Document::loadMainDependencies(); + } + + public function onAfterRender() + { + if ( ! is_file(JPATH_LIBRARIES . '/regularlabs/autoload.php')) + { + return; + } + + if ( ! RL_Document::isAdmin(true) || ! RL_Document::isHtml() + ) + { + return; + } + + RL_AdminMenu::combine(); + + RL_AdminMenu::addHelpItem(); + } + + public function onInstallerBeforePackageDownload(&$url, &$headers) + { + $uri = JUri::getInstance($url); + $host = $uri->getHost(); + + if ( + strpos($host, 'regularlabs.com') === false + && strpos($host, 'nonumber.nl') === false + ) + { + return true; + } + + $uri->setScheme('https'); + $uri->setHost('download.regularlabs.com'); + $uri->delVar('pro'); + $url = $uri->toString(); + + $params = RL_Parameters::getInstance()->getComponentParams('regularlabsmanager'); + + if (empty($params) || empty($params->key)) + { + return true; + } + + $uri->setVar('k', $params->key); + $url = $uri->toString(); + + return true; + } + + public function onAjaxRegularLabs() + { + $input = JFactory::getApplication()->input; + + $format = $input->getString('format', 'json'); + + $attributes = RL_Uri::getCompressedAttributes(); + $attributes = new Registry($attributes); + + $field = $attributes->get('field'); + $field_type = $attributes->get('fieldtype'); + + $class = $this->getAjaxClass($field, $field_type); + + if (empty($class) || ! class_exists($class)) + { + return false; + } + + $type = isset($attributes->type) ? $attributes->type : ''; + + $method = 'getAjax' . ucfirst($format) . ucfirst($type); + + $class = new $class; + + if ( ! method_exists($class, $method)) + { + return false; + } + + echo $class->$method($attributes); + } + + public function getAjaxClass($field, $field_type = '') + { + if (empty($field)) + { + return false; + } + + if ($field_type) + { + return $this->getFieldClass($field, $field_type); + } + + $file = JPATH_LIBRARIES . '/regularlabs/fields/' . strtolower($field) . '.php'; + + if ( ! file_exists($file)) + { + return false; + } + + require_once $file; + + return 'JFormFieldRL_' . ucfirst($field); + } + + public function getFieldClass($field, $field_type) + { + $file = JPATH_PLUGINS . '/fields/' . strtolower($field_type) . '/fields/' . strtolower($field) . '.php'; + + if ( ! file_exists($file)) + { + return false; + } + + require_once $file; + + return 'JFormField' . ucfirst($field); + } +} + diff --git a/deployed/regularlabs/plugins/system/regularlabs/regularlabs.xml b/deployed/regularlabs/plugins/system/regularlabs/regularlabs.xml new file mode 100644 index 00000000..f84482fa --- /dev/null +++ b/deployed/regularlabs/plugins/system/regularlabs/regularlabs.xml @@ -0,0 +1,51 @@ + + + plg_system_regularlabs + PLG_SYSTEM_REGULARLABS_DESC + 18.12.3953 + December 2018 + Regular Labs (Peter van Westen) + info@regularlabs.com + https://www.regularlabs.com + Copyright © 2018 Regular Labs - All Rights Reserved + http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + + script.install.php + + + regularlabs.php + script.install.helper.php + language + src + vendor + + + + +
+ +
+ +
+ + + + + + + + + +
+
+
+
diff --git a/deployed/regularlabs/plugins/system/regularlabs/script.install.helper.php b/deployed/regularlabs/plugins/system/regularlabs/script.install.helper.php new file mode 100644 index 00000000..607ca01a --- /dev/null +++ b/deployed/regularlabs/plugins/system/regularlabs/script.install.helper.php @@ -0,0 +1,878 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +class PlgSystemRegularLabsInstallerScriptHelper +{ + public $name = ''; + public $alias = ''; + public $extname = ''; + public $extension_type = ''; + public $plugin_folder = 'system'; + public $module_position = 'status'; + public $client_id = 1; + public $install_type = 'install'; + public $show_message = true; + public $db = null; + public $softbreak = null; + public $installed_version = ''; + + public function __construct(&$params) + { + $this->extname = $this->extname ?: $this->alias; + $this->db = JFactory::getDbo(); + } + + public function preflight($route, JAdapterInstance $adapter) + { + if ( ! in_array($route, ['install', 'update'])) + { + return true; + } + + JFactory::getLanguage()->load('plg_system_regularlabsinstaller', JPATH_PLUGINS . '/system/regularlabsinstaller'); + + $this->installed_version = $this->getVersion($this->getInstalledXMLFile()); + + if ($this->show_message && $this->isInstalled()) + { + $this->install_type = 'update'; + } + + if ($this->onBeforeInstall($route) === false) + { + return false; + } + + return true; + } + + public function postflight($route, JAdapterInstance $adapter) + { + $this->removeGlobalLanguageFiles(); + $this->removeUnusedLanguageFiles(); + + JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, $this->getMainFolder()); + + if ( ! in_array($route, ['install', 'update'])) + { + return true; + } + + $this->fixExtensionNames(); + $this->updateUpdateSites(); + $this->removeAdminCache(); + + if ($this->onAfterInstall($route) === false) + { + return false; + } + + if ($route == 'install') + { + $this->publishExtension(); + } + + if ($this->show_message) + { + $this->addInstalledMessage(); + } + + JFactory::getCache()->clean('com_plugins'); + JFactory::getCache()->clean('_system'); + + return true; + } + + public function isInstalled() + { + if ( ! is_file($this->getInstalledXMLFile())) + { + return false; + } + + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('extension_id')) + ->from('#__extensions') + ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($this->extension_type)) + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName())); + $this->db->setQuery($query, 0, 1); + $result = $this->db->loadResult(); + + return empty($result) ? false : true; + } + + public function getMainFolder() + { + switch ($this->extension_type) + { + case 'plugin' : + return JPATH_PLUGINS . '/' . $this->plugin_folder . '/' . $this->extname; + + case 'component' : + return JPATH_ADMINISTRATOR . '/components/com_' . $this->extname; + + case 'module' : + return JPATH_ADMINISTRATOR . '/modules/mod_' . $this->extname; + + case 'library' : + return JPATH_SITE . '/libraries/' . $this->extname; + } + } + + public function getInstalledXMLFile() + { + return $this->getXMLFile($this->getMainFolder()); + } + + public function getCurrentXMLFile() + { + return $this->getXMLFile(__DIR__); + } + + public function getXMLFile($folder) + { + switch ($this->extension_type) + { + case 'module' : + return $folder . '/mod_' . $this->extname . '.xml'; + + default : + return $folder . '/' . $this->extname . '.xml'; + } + } + + public function uninstallExtension($extname, $type = 'plugin', $folder = 'system', $show_message = true) + { + if (empty($extname)) + { + return; + } + + $folders = []; + + switch ($type) + { + case 'plugin'; + $folders[] = JPATH_PLUGINS . '/' . $folder . '/' . $extname; + break; + + case 'component': + $folders[] = JPATH_ADMINISTRATOR . '/components/com_' . $extname; + $folders[] = JPATH_SITE . '/components/com_' . $extname; + break; + + case 'module': + $folders[] = JPATH_ADMINISTRATOR . '/modules/mod_' . $extname; + $folders[] = JPATH_SITE . '/modules/mod_' . $extname; + break; + } + + if ( ! $this->foldersExist($folders)) + { + return; + } + + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('extension_id')) + ->from('#__extensions') + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->getElementName($type, $extname))) + ->where($this->db->quoteName('type') . ' = ' . $this->db->quote($type)); + + if ($type == 'plugin') + { + $query->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($folder)); + } + + $this->db->setQuery($query); + $ids = $this->db->loadColumn(); + + if (empty($ids)) + { + foreach ($folders as $folder) + { + JFactory::getApplication()->enqueueMessage('2. Deleting: ' . $folder, 'notice'); + JFolder::delete($folder); + } + + return; + } + + $ignore_ids = JFactory::getApplication()->getUserState('rl_ignore_uninstall_ids', []); + + if (JFactory::getApplication()->input->get('option') == 'com_installer' && JFactory::getApplication()->input->get('task') == 'remove') + { + // Don't attempt to uninstall extensions that are already selected to get uninstalled by them selves + $ignore_ids = array_merge($ignore_ids, JFactory::getApplication()->input->get('cid', [], 'array')); + JFactory::getApplication()->input->set('cid', array_merge($ignore_ids, $ids)); + } + + $ids = array_diff($ids, $ignore_ids); + + if (empty($ids)) + { + return; + } + + $ignore_ids = array_merge($ignore_ids, $ids); + JFactory::getApplication()->setUserState('rl_ignore_uninstall_ids', $ignore_ids); + + foreach ($ids as $id) + { + $tmpInstaller = new JInstaller; + $tmpInstaller->uninstall($type, $id); + } + + if ($show_message) + { + JFactory::getApplication()->enqueueMessage( + JText::sprintf( + 'COM_INSTALLER_UNINSTALL_SUCCESS', + JText::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($type)) + ) + ); + } + } + + public function foldersExist($folders = []) + { + foreach ($folders as $folder) + { + if (is_dir($folder)) + { + return true; + } + } + + return false; + } + + public function uninstallPlugin($extname, $folder = 'system', $show_message = true) + { + $this->uninstallExtension($extname, 'plugin', $folder, $show_message); + } + + public function uninstallComponent($extname, $show_message = true) + { + $this->uninstallExtension($extname, 'component', null, $show_message); + } + + public function uninstallModule($extname, $show_message = true) + { + $this->uninstallExtension($extname, 'module', null, $show_message); + } + + public function publishExtension() + { + switch ($this->extension_type) + { + case 'plugin' : + $this->publishPlugin(); + + case 'module' : + $this->publishModule(); + } + } + + public function publishPlugin() + { + $query = $this->db->getQuery(true) + ->update('#__extensions') + ->set($this->db->quoteName('enabled') . ' = 1') + ->where($this->db->quoteName('type') . ' = ' . $this->db->quote('plugin')) + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote($this->extname)) + ->where($this->db->quoteName('folder') . ' = ' . $this->db->quote($this->plugin_folder)); + $this->db->setQuery($query); + $this->db->execute(); + } + + public function publishModule() + { + // Get module id + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('id')) + ->from('#__modules') + ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) + ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + if ( ! $id) + { + return; + } + + // check if module is already in the modules_menu table (meaning is is already saved) + $query->clear() + ->select($this->db->quoteName('moduleid')) + ->from('#__modules_menu') + ->where($this->db->quoteName('moduleid') . ' = ' . (int) $id); + $this->db->setQuery($query, 0, 1); + $exists = $this->db->loadResult(); + + if ($exists) + { + return; + } + + // Get highest ordering number in position + $query->clear() + ->select($this->db->quoteName('ordering')) + ->from('#__modules') + ->where($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) + ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id) + ->order('ordering DESC'); + $this->db->setQuery($query, 0, 1); + $ordering = $this->db->loadResult(); + $ordering++; + + // publish module and set ordering number + $query->clear() + ->update('#__modules') + ->set($this->db->quoteName('published') . ' = 1') + ->set($this->db->quoteName('ordering') . ' = ' . (int) $ordering) + ->set($this->db->quoteName('position') . ' = ' . $this->db->quote($this->module_position)) + ->where($this->db->quoteName('id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + + // add module to the modules_menu table + $query->clear() + ->insert('#__modules_menu') + ->columns([$this->db->quoteName('moduleid'), $this->db->quoteName('menuid')]) + ->values((int) $id . ', 0'); + $this->db->setQuery($query); + $this->db->execute(); + } + + public function addInstalledMessage() + { + JFactory::getApplication()->enqueueMessage( + JText::sprintf( + JText::_($this->install_type == 'update' ? 'RLI_THE_EXTENSION_HAS_BEEN_UPDATED_SUCCESSFULLY' : 'RLI_THE_EXTENSION_HAS_BEEN_INSTALLED_SUCCESSFULLY'), + '' . JText::_($this->name) . '', + '' . $this->getVersion() . '', + $this->getFullType() + ) + ); + } + + public function getPrefix() + { + switch ($this->extension_type) + { + case 'plugin'; + return JText::_('plg_' . strtolower($this->plugin_folder)); + + case 'component': + return JText::_('com'); + + case 'module': + return JText::_('mod'); + + case 'library': + return JText::_('lib'); + + default: + return $this->extension_type; + } + } + + public function getElementName($type = null, $extname = null) + { + $type = is_null($type) ? $this->extension_type : $type; + $extname = is_null($extname) ? $this->extname : $extname; + + switch ($type) + { + case 'component' : + return 'com_' . $extname; + + case 'module' : + return 'mod_' . $extname; + + case 'plugin' : + default: + return $extname; + } + } + + public function getFullType() + { + return JText::_('RLI_' . strtoupper($this->getPrefix())); + } + + public function getVersion($file = '') + { + $file = $file ?: $this->getCurrentXMLFile(); + + if ( ! is_file($file)) + { + return ''; + } + + $xml = JApplicationHelper::parseXMLInstallFile($file); + + if ( ! $xml || ! isset($xml['version'])) + { + return ''; + } + + return $xml['version']; + } + + public function isNewer() + { + if ( ! $this->installed_version) + { + return true; + } + + $package_version = $this->getVersion(); + + return version_compare($this->installed_version, $package_version, '<='); + } + + public function canInstall() + { + // The extension is not installed yet + if ( ! $this->installed_version) + { + return true; + } + + // The free version is installed. So any version is ok to install + if (strpos($this->installed_version, 'PRO') === false) + { + return true; + } + + // Current package is a pro version, so all good + if (strpos($this->getVersion(), 'PRO') !== false) + { + return true; + } + + JFactory::getLanguage()->load($this->getPrefix() . '_' . $this->extname, __DIR__); + + JFactory::getApplication()->enqueueMessage(JText::_('RLI_ERROR_PRO_TO_FREE'), 'error'); + + JFactory::getApplication()->enqueueMessage( + html_entity_decode( + JText::sprintf( + 'RLI_ERROR_UNINSTALL_FIRST', + '', + '', + JText::_($this->name) + ) + ), 'error' + ); + + return false; + } + + /* + * Fixes incorrectly formed versions because of issues in old packager + */ + public function fixFileVersions($file) + { + if (is_array($file)) + { + foreach ($file as $f) + { + self::fixFileVersions($f); + } + + return; + } + + if ( ! is_string($file) || ! is_file($file)) + { + return; + } + + $contents = file_get_contents($file); + + if ( + strpos($contents, 'FREEFREE') === false + && strpos($contents, 'FREEPRO') === false + && strpos($contents, 'PROFREE') === false + && strpos($contents, 'PROPRO') === false + ) + { + return; + } + + $contents = str_replace( + ['FREEFREE', 'FREEPRO', 'PROFREE', 'PROPRO'], + ['FREE', 'PRO', 'FREE', 'PRO'], + $contents + ); + + JFile::write($file, $contents); + } + + public function onBeforeInstall($route) + { + if ( ! $this->canInstall()) + { + return false; + } + + return true; + } + + public function onAfterInstall($route) + { + } + + public function delete($files = []) + { + foreach ($files as $file) + { + if (is_dir($file)) + { + JFolder::delete($file); + } + + if (is_file($file)) + { + JFile::delete($file); + } + } + } + + public function fixAssetsRules() + { + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('rules')) + ->from('#__assets') + ->where($this->db->quoteName('title') . ' = ' . $this->db->quote('com_' . $this->extname)); + $this->db->setQuery($query, 0, 1); + $rules = $this->db->loadResult(); + + $rules = json_decode($rules); + + if(empty($rules)) { + return; + } + + foreach($rules as $key => $value) { + if(!empty($value)) { + continue; + } + + unset($rules->$key); + } + + $rules = json_encode($rules); + + + $query = $this->db->getQuery(true) + ->update($this->db->quoteName('#__assets')) + ->set($this->db->quoteName('rules') . ' = ' . $this->db->quote($rules)) + ->where($this->db->quoteName('title') . ' = ' . $this->db->quote('com_' . $this->extname)); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function fixExtensionNames() + { + switch ($this->extension_type) + { + case 'module' : + $this->fixModuleNames(); + } + } + + private function fixModuleNames() + { + // Get module id + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('id')) + ->from('#__modules') + ->where($this->db->quoteName('module') . ' = ' . $this->db->quote('mod_' . $this->extname)) + ->where($this->db->quoteName('client_id') . ' = ' . (int) $this->client_id); + $this->db->setQuery($query, 0, 1); + $module_id = $this->db->loadResult(); + + if (empty($module_id)) + { + return; + } + + $title = 'Regular Labs - ' . JText::_($this->name); + + $query->clear() + ->update('#__modules') + ->set($this->db->quoteName('title') . ' = ' . $this->db->quote($title)) + ->where($this->db->quoteName('id') . ' = ' . (int) $module_id) + ->where($this->db->quoteName('title') . ' LIKE ' . $this->db->quote('NoNumber%')); + $this->db->setQuery($query); + $this->db->execute(); + + // Fix module assets + + // Get asset id + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('id')) + ->from('#__assets') + ->where($this->db->quoteName('name') . ' = ' . $this->db->quote('com_modules.module.' . (int) $module_id)) + ->where($this->db->quoteName('title') . ' LIKE ' . $this->db->quote('NoNumber%')); + $this->db->setQuery($query, 0, 1); + $asset_id = $this->db->loadResult(); + + if (empty($asset_id)) + { + return; + } + + $query->clear() + ->update('#__assets') + ->set($this->db->quoteName('title') . ' = ' . $this->db->quote($title)) + ->where($this->db->quoteName('id') . ' = ' . (int) $asset_id); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function updateUpdateSites() + { + $this->removeOldUpdateSites(); + $this->updateNamesInUpdateSites(); + $this->updateHttptoHttpsInUpdateSites(); + $this->removeDuplicateUpdateSite(); + $this->updateDownloadKey(); + } + + private function removeOldUpdateSites() + { + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('nonumber.nl%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + if ( ! $id) + { + return; + } + + $query->clear() + ->delete('#__update_sites') + ->where($this->db->quoteName('update_site_id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + + $query->clear() + ->delete('#__update_sites_extensions') + ->where($this->db->quoteName('update_site_id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function updateNamesInUpdateSites() + { + $name = JText::_($this->name); + if ($this->alias != 'extensionmanager') + { + $name = 'Regular Labs - ' . $name; + } + + $query = $this->db->getQuery(true) + ->update('#__update_sites') + ->set($this->db->quoteName('name') . ' = ' . $this->db->quote($name)) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function updateHttptoHttpsInUpdateSites() + { + $query = $this->db->getQuery(true) + ->update('#__update_sites') + ->set($this->db->quoteName('location') . ' = REPLACE(' + . $this->db->quoteName('location') . ', ' + . $this->db->quote('http://') . ', ' + . $this->db->quote('https://') + . ')') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('http://download.regularlabs.com%')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function removeDuplicateUpdateSite() + { + // First check to see if there is a pro entry + + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')) + ->where($this->db->quoteName('location') . ' NOT LIKE ' . $this->db->quote('%pro=1%')); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + // Otherwise just get the first match + if ( ! $id) + { + $query->clear() + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')); + $this->db->setQuery($query, 0, 1); + $id = $this->db->loadResult(); + + // Remove pro=1 from the found update site + $query->clear() + ->update('#__update_sites') + ->set($this->db->quoteName('location') + . ' = replace(' . $this->db->quoteName('location') . ', ' . $this->db->quote('&pro=1') . ', ' . $this->db->quote('') . ')') + ->where($this->db->quoteName('update_site_id') . ' = ' . (int) $id); + $this->db->setQuery($query); + $this->db->execute(); + } + + if ( ! $id) + { + return; + } + + $query->clear() + ->select($this->db->quoteName('update_site_id')) + ->from('#__update_sites') + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%e=' . $this->alias . '%')) + ->where($this->db->quoteName('update_site_id') . ' != ' . $id); + $this->db->setQuery($query); + $ids = $this->db->loadColumn(); + + if (empty($ids)) + { + return; + } + + $query->clear() + ->delete('#__update_sites') + ->where($this->db->quoteName('update_site_id') . ' IN (' . implode(',', $ids) . ')'); + $this->db->setQuery($query); + $this->db->execute(); + + $query->clear() + ->delete('#__update_sites_extensions') + ->where($this->db->quoteName('update_site_id') . ' IN (' . implode(',', $ids) . ')'); + $this->db->setQuery($query); + $this->db->execute(); + } + + // Save the download key from the Regular Labs Extension Manager config to the update sites + private function updateDownloadKey() + { + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('params')) + ->from('#__extensions') + ->where($this->db->quoteName('element') . ' = ' . $this->db->quote('com_regularlabsmanager')); + $this->db->setQuery($query); + $params = $this->db->loadResult(); + + if ( ! $params) + { + return; + } + + $params = json_decode($params); + + if ( ! isset($params->key)) + { + return; + } + + // Add the key on all regularlabs.com urls + $query->clear() + ->update('#__update_sites') + ->set($this->db->quoteName('extra_query') . ' = ' . $this->db->quote('k=' . $params->key)) + ->where($this->db->quoteName('location') . ' LIKE ' . $this->db->quote('%download.regularlabs.com%')); + $this->db->setQuery($query); + $this->db->execute(); + } + + private function removeAdminCache() + { + $this->delete([JPATH_ADMINISTRATOR . '/cache/regularlabs']); + $this->delete([JPATH_ADMINISTRATOR . '/cache/nonumber']); + } + + private function removeGlobalLanguageFiles() + { + if ($this->extension_type == 'library') + { + return; + } + + $language_files = JFolder::files(JPATH_ADMINISTRATOR . '/language', '\.' . $this->getPrefix() . '_' . $this->extname . '\.', true, true); + + // Remove override files + foreach ($language_files as $i => $language_file) + { + if (strpos($language_file, '/overrides/') === false) + { + continue; + } + + unset($language_files[$i]); + } + + if (empty($language_files)) + { + return; + } + + JFile::delete($language_files); + } + + private function removeUnusedLanguageFiles() + { + if ($this->extension_type == 'library') + { + return; + } + + $installed_languages = array_merge( + JFolder::folders(JPATH_SITE . '/language'), + JFolder::folders(JPATH_ADMINISTRATOR . '/language') + ); + + $languages = array_diff( + JFolder::folders(__DIR__ . '/language'), + $installed_languages + ); + + $delete_languages = []; + + foreach ($languages as $language) + { + $delete_languages[] = $this->getMainFolder() . '/language/' . $language; + } + + if (empty($delete_languages)) + { + return; + } + + // Remove folders + $this->delete($delete_languages); + } +} diff --git a/deployed/regularlabs/plugins/system/regularlabs/script.install.php b/deployed/regularlabs/plugins/system/regularlabs/script.install.php new file mode 100644 index 00000000..1f220d9a --- /dev/null +++ b/deployed/regularlabs/plugins/system/regularlabs/script.install.php @@ -0,0 +1,51 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +defined('_JEXEC') or die; + +if ( ! class_exists('PlgSystemRegularLabsInstallerScript')) +{ + require_once __DIR__ . '/script.install.helper.php'; + + class PlgSystemRegularLabsInstallerScript extends PlgSystemRegularLabsInstallerScriptHelper + { + public $name = 'REGULAR_LABS_LIBRARY'; + public $alias = 'regularlabs'; + public $extension_type = 'plugin'; + public $show_message = false; + + public function onBeforeInstall($route) + { + if ( ! $this->isNewer()) + { + $this->softbreak = true; + + return false; + } + + return true; + } + + public function uninstall($adapter) + { + $this->deleteLibrary(); + } + + private function deleteLibrary() + { + $this->delete( + [ + JPATH_LIBRARIES . '/regularlabs', + ] + ); + } + } +} diff --git a/deployed/regularlabs/plugins/system/regularlabs/src/AdminMenu.php b/deployed/regularlabs/plugins/system/regularlabs/src/AdminMenu.php new file mode 100644 index 00000000..e6be2d3e --- /dev/null +++ b/deployed/regularlabs/plugins/system/regularlabs/src/AdminMenu.php @@ -0,0 +1,155 @@ + + * @link http://www.regularlabs.com + * @copyright Copyright © 2018 Regular Labs All Rights Reserved + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + */ + +namespace RegularLabs\Plugin\System\RegularLabs; + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory as JFactory; +use RegularLabs\Library\RegEx as RL_RegEx; + +class AdminMenu +{ + public static function combine() + { + $params = Params::get(); + + if ( ! $params->combine_admin_menu) + { + return; + } + + $html = JFactory::getApplication()->getBody(); + + if ($html == '') + { + return; + } + + if (strpos($html, '